def test_get_devices(session): """Test getting device list.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "_metadata": { "count": 1, "next": None, "previous": None, }, "results": [{ "url": "mock_url", "id": "mock_id", "version": 2, }], } session._client_session.request.return_value = resp device = session.loop.run_until_complete(session.get_devices())[0] assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "GET" assert session._client_session.request.mock_calls[0][1][1] == \ "https://api.automatic.com/device?" assert device.url == "mock_url" assert device.id == "mock_id" assert device.version == 2
def test_api_post(aiohttp_session): """Test the post api object method.""" mock_kwargs = { "timeout": 10, } obj = base.BaseApiObject(None, request_kwargs=mock_kwargs, client_session=aiohttp_session) resp = AsyncMock() resp.status = 200 mock_json = { "mock_attr", "mock_val", } resp.json.return_value = mock_json aiohttp_session.request.return_value = resp mock_request = { "request_attr": "request_data", } result = aiohttp_session.loop.run_until_complete( obj._post("mock_url", mock_request)) assert result == mock_json assert aiohttp_session.request.called assert len(aiohttp_session.request.mock_calls) == 2 assert aiohttp_session.request.mock_calls[0][1][0] == "POST" assert aiohttp_session.request.mock_calls[0][1][1] == "mock_url" assert aiohttp_session.request.mock_calls[0][2]["data"] == mock_request assert aiohttp_session.request.mock_calls[0][2]["timeout"] == 10
def test_create_session_from_password(client): """Test opening a session from the users password.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "access_token": "mock_access", "expires_in": 123456, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), "refresh_token": "mock_refresh", "token_type": "Bearer", } client._client_session.request.return_value = resp client.loop.run_until_complete( client.create_session_from_password(['location', 'trip'], "mock_user", "mock_pass")) assert client._client_session.request.called assert len(client._client_session.request.mock_calls) == 2 assert client._client_session.request.mock_calls[0][1][0] == "POST" assert client._client_session.request.mock_calls[0][1][1] == \ "https://accounts.automatic.com/oauth/access_token" assert client._client_session.request.mock_calls[0][2]['data'] == { "client_id": client.client_id, "client_secret": client.client_secret, "grant_type": "password", "username": "******", "password": "******", "scope": ("scope:location scope:trip"), }
def test_create_session_from_oauth_code(client): """Test opening a session from an oauth code.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "access_token": "mock_access", "expires_in": 123456, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), "refresh_token": "mock_refresh", "token_type": "bearer", } client._client_session.request.return_value = resp client.state = "mock_state" session = client.loop.run_until_complete( client.create_session_from_oauth_code("mock_code", "mock_state")) assert client._client_session.request.called assert len(client._client_session.request.mock_calls) == 2 assert client._client_session.request.mock_calls[0][1][0] == "POST" assert client._client_session.request.mock_calls[0][1][1] == \ "https://accounts.automatic.com/oauth/access_token" assert client._client_session.request.mock_calls[0][2]['data'] == { "client_id": client.client_id, "client_secret": client.client_secret, "grant_type": "authorization_code", "code": "mock_code", } assert session.refresh_token == "mock_refresh"
def test_request_status_error(aiohttp_session): """Test the api request client error.""" obj = base.BaseApiObject(None, client_session=aiohttp_session) resp = AsyncMock() resp.status = 500 resp.json.return_value = {"error": "mock_error"} aiohttp_session.request.return_value = resp with pytest.raises(exceptions.InternalError): aiohttp_session.loop.run_until_complete(obj._request("GET", "url", {}))
def test_scope_forbidden(client): """Test opening a session from an invalid token.""" resp = AsyncMock() resp.status = 403 resp.json.return_value = { "error": "access_denied", } client._client_session.request.return_value = resp with pytest.raises(exceptions.ForbiddenError): client.loop.run_until_complete( client.create_session_from_refresh_token("bad_token"))
def test_scope_forbidden(client): """Test opening a session from the users password.""" resp = AsyncMock() resp.status = 403 resp.json.return_value = { "error": "access_denied", } client._client_session.request.return_value = resp with pytest.raises(exceptions.ForbiddenError): client.loop.run_until_complete( client.create_session_from_password(['location', 'trip'], "mock_user", "mock_pass"))
def test_request_status_bad_json(aiohttp_session): """Test the api request client error.""" obj = base.BaseApiObject(None, client_session=aiohttp_session) resp = AsyncMock() resp.status = 200 def side_effect(*args, **kwargs): raise ValueError() resp.json.side_effect = side_effect aiohttp_session.request.return_value = resp with pytest.raises(exceptions.InvalidResponseError): aiohttp_session.loop.run_until_complete(obj._request("GET", "url", {}))
def test_get_engineio_session_empty_packet(mock_time, client): """Test error requesting an engineIO session from Automatic.""" resp = AsyncMock() resp.status = 200 # Simulate an empty packet return resp.read.return_value = b'' client._client_session.request.return_value = resp with pytest.raises(exceptions.TransportError) as exc: client.loop.run_until_complete(client._get_engineio_session()) assert str(exc.value) == \ "engineIO session packet not received"
def test_get_engineio_session_error(mock_time, client): """Test error requesting an engineIO session from Automatic.""" resp = AsyncMock() resp.status = 200 data = 'Error Requesting Session'.encode('utf-8') length_str = str(len(data)).encode('utf-8') # Build engineIO session create packet resp.read.return_value = \ b'\x01\x00' + length_str + b'\xFF\xFF4' + data client._client_session.request.return_value = resp with pytest.raises(exceptions.TransportError) as exc: client.loop.run_until_complete(client._get_engineio_session()) assert str(exc.value) == \ "engineIO packet is not open type: Error Requesting Session"
def test_get_vehicles(session): """Test getting vehicle list.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "_metadata": { "count": 1, "next": None, "previous": None, }, "results": [{ "url": "mock_url", "id": "mock_id", "make": "mock_make", "model": "mock_model", "submodel": None, "created_at": "2015-03-20T01:43:36.738000Z", "fuel_level_percent": 73.9, }], } session._client_session.request.return_value = resp dt = datetime(2017, 1, 28) vehicle = session.loop.run_until_complete( session.get_vehicles(vin="VINVIN", created_at__gte=dt))[0] assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "GET" assert session._client_session.request.mock_calls[0][1][1][:34] == \ "https://api.automatic.com/vehicle?" assert vehicle.url == "mock_url" assert vehicle.id == "mock_id" assert vehicle.make == "mock_make" assert vehicle.model == "mock_model" assert vehicle.vin is None assert vehicle.submodel is None assert vehicle.created_at == datetime(2015, 3, 20, 1, 43, 36, 738000, tzinfo=timezone.utc) assert vehicle.fuel_level_percent == 73.9
def test_session_auto_refresh(aiohttp_session): """Test auto-refreshing a session with the refresh token.""" client = AsyncMock() client.client_session = aiohttp_session client.request_kwargs = {} data = { "access_token": "123", "refresh_token": "ABCD", "expires_in": 12345, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), } resp = AsyncMock() resp.status = 200 resp.json.return_value = { "access_token": "mock_access", "expires_in": 123456, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), "refresh_token": "mock_refresh", "token_type": "Bearer", } with patch.object(aiohttp_session.loop, 'call_at') as mock_call_at: session = Session(client, **data) assert mock_call_at.called assert len(mock_call_at.mock_calls) == 1 with patch.object(aiohttp_session.loop, 'create_task'): with patch.object(session, 'refresh') as mock_refresh: assert not mock_refresh.called mock_call_at.mock_calls[0][1][1]() assert mock_refresh.called assert len(mock_refresh.mock_calls) == 1
def test_result_previous_list(session): """Test the result object get previous list.""" obj = base.ResultList(parent=session, item_class=MockDataObject, resp={ "_metadata": { "count": 0, "next": None, "previous": "previous_url", }, "results": [], }) resp = AsyncMock() resp.status = 200 mock_json = { "_metadata": { "count": 2, "next": None, "previous": None, }, "results": [{ "attr1": "value1", "attr2": "value2", }, { "attr1": "value3" }], } resp.json.return_value = mock_json session._client_session.request.return_value = resp next_list = session.loop.run_until_complete(obj.get_next()) previous_list = session.loop.run_until_complete(obj.get_previous()) assert obj.next is None assert next_list is None assert len(obj) == 0 assert obj.previous is "previous_url" assert len(obj) == 0 assert len(previous_list) == 2 assert sorted([item.attr1 for item in previous_list]) == \ sorted(["value1", "value3"])
def test_get_engineio_session(mock_time, client): """Test requesting an engineIO session from Automatic.""" resp = AsyncMock() resp.status = 200 data = json.dumps({ "sid": "mock_session_id", "pingTimeout": 12345, "pingInterval": 23456, }).encode('utf-8') length_str = str(len(data)).encode('utf-8') # Build engineIO session create packet resp.read.return_value = \ b'\x01\x00' + length_str + b'\xFF\xFF0' + data client._client_session.request.return_value = resp session_data = client.loop.run_until_complete( client._get_engineio_session()) assert client._client_session.request.called assert len(client._client_session.request.mock_calls) == 2 assert client._client_session.request.mock_calls[0][1][0] == "GET" assert client._client_session.request.mock_calls[0][1][1][:40] == \ "https://stream.automatic.com/socket.io/?" query = client._client_session.request.mock_calls[0][1][1][40:].split('&') params = {} for item in query: k, v = item.split('=') params[k] = v assert params == { "EIO": "3", "token": "mock_id:mock_secret", "transport": "polling", "t": "1493426946.123-0", } assert session_data == { "sid": "mock_session_id", "pingTimeout": 12.345, "pingInterval": 23.456, }
def test_session_refresh(session): """Test refreshing a session with the refresh token.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "access_token": "mock_access", "expires_in": 123456, "scope": ("scope:location scope:vehicle:profile " "scope:user:profile scope:trip"), "refresh_token": "mock_refresh", "token_type": "Bearer", } session._client_session.request.return_value = resp refresh_token = session._refresh_token renew_handle = MagicMock() session._renew_handle = renew_handle session._client.client_id = "123" session._client.client_secret = "456" session.loop.run_until_complete(session.refresh()) assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "POST" assert session._client_session.request.mock_calls[0][1][1] == \ "https://accounts.automatic.com/oauth/access_token" assert session._client_session.request.mock_calls[0][2]['data'] == { "client_id": "123", "client_secret": "456", "grant_type": "refresh_token", "refresh_token": refresh_token, } assert renew_handle.cancel.called
def test_get_user(session): """Test getting user information.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "url": "mock_url", "id": "mock_id", "username": "******", "first_name": "mock_firstname", "email": "*****@*****.**", } session._client_session.request.return_value = resp user = session.loop.run_until_complete(session.get_user()) assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "GET" assert session._client_session.request.mock_calls[0][1][1] == \ "https://api.automatic.com/user/me" assert user.url == "mock_url" assert user.id == "mock_id" assert user.username == "mock_username" assert user.first_name == "mock_firstname" assert user.last_name is None assert user.email == "*****@*****.**" session._client_session.request.reset_mock() resp.json.return_value = { "url": "mock_profile_url", "user": "******", "date_joined": "2015-03-20T01:43:36.738000Z", } profile = session.loop.run_until_complete(user.get_profile()) assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "GET" assert session._client_session.request.mock_calls[0][1][1] == \ "https://api.automatic.com/user/mock_id/profile" assert profile.url == "mock_profile_url" assert profile.user == "mock_user" assert profile.date_joined == datetime(2015, 3, 20, 1, 43, 36, 738000, tzinfo=timezone.utc) session._client_session.request.reset_mock() resp.json.return_value = { "url": "mock_metadata_url", "user": "******", "firmware_version": "1.2.3.4", "is_app_latest_version": False, "is_staff": True, } metadata = session.loop.run_until_complete(user.get_metadata()) assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "GET" assert session._client_session.request.mock_calls[0][1][1] == \ "https://api.automatic.com/user/mock_id/metadata" assert metadata.url == "mock_metadata_url" assert metadata.user == "mock_user" assert metadata.firmware_version == "1.2.3.4" assert metadata.app_version is None assert metadata.is_app_latest_version is False assert metadata.is_staff is True
def test_get_trips(session): """Test getting trip list.""" resp = AsyncMock() resp.status = 200 resp.json.return_value = { "_metadata": { "count": 1, "next": None, "previous": None, }, "results": [{ "url": "mock_url", "id": "mock_id", "driver": "mock_driver", "user": "******", "start_location": { "lat": 43.12345, "lon": 34.54321, "accuracy_m": 12.2, }, "end_location": { "lat": 53.12345, "lon": 44.54321, "accuracy_m": 11.2, }, "start_address": { "name": "123 Fake St", }, "end_address": { "name": "456 Elm", }, "hard_brakes": 2, "path": None, "started_at": "2015-03-21T01:43:36.738000Z", "ended_at": "2015-03-21T04:45:36.738000Z", "tags": ["business"], }], } session._client_session.request.return_value = resp dt = datetime(2017, 1, 28) trip = session.loop.run_until_complete( session.get_trips(vehicle="vehicle_id", started_at__gte=dt))[0] assert session._client_session.request.called assert len(session._client_session.request.mock_calls) == 2 assert session._client_session.request.mock_calls[0][1][0] == "GET" assert session._client_session.request.mock_calls[0][1][1][:31] == \ "https://api.automatic.com/trip?" assert trip.url == "mock_url" assert trip.id == "mock_id" assert trip.driver == "mock_driver" assert trip.user == "mock_user" assert trip.fuel_cost_usd is None assert trip.start_location.lat == 43.12345 assert trip.start_location.lon == 34.54321 assert trip.start_location.accuracy_m == 12.2 assert trip.end_location.lat == 53.12345 assert trip.end_location.lon == 44.54321 assert trip.end_location.accuracy_m == 11.2 assert trip.start_address.name == "123 Fake St" assert trip.start_address.display_name is None assert trip.end_address.name == "456 Elm" assert trip.end_address.display_name is None assert trip.hard_brakes == 2 assert trip.path is None assert trip.started_at == datetime(2015, 3, 21, 1, 43, 36, 738000, tzinfo=timezone.utc) assert trip.ended_at == datetime(2015, 3, 21, 4, 45, 36, 738000, tzinfo=timezone.utc) assert trip.tags == ["business"]