core/tests/components/renault/conftest.py

220 lines
8.1 KiB
Python
Raw Normal View History

"""Provide common Renault fixtures."""
import contextlib
from types import MappingProxyType
from typing import Any
from unittest.mock import patch
import pytest
from renault_api.kamereon import exceptions, schemas
from renault_api.renault_account import RenaultAccount
from homeassistant.components.renault.const import DOMAIN
from homeassistant.config_entries import SOURCE_USER, ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
from .const import MOCK_ACCOUNT_ID, MOCK_CONFIG, MOCK_VEHICLES
from tests.common import MockConfigEntry, load_fixture
@pytest.fixture(name="vehicle_type", params=MOCK_VEHICLES.keys())
def get_vehicle_type(request: pytest.FixtureRequest) -> str:
"""Parametrize vehicle type."""
return request.param
@pytest.fixture(name="config_entry")
def get_config_entry(hass: HomeAssistant) -> ConfigEntry:
"""Create and register mock config entry."""
config_entry = MockConfigEntry(
domain=DOMAIN,
source=SOURCE_USER,
data=MOCK_CONFIG,
unique_id=MOCK_ACCOUNT_ID,
options={},
entry_id="123456",
)
config_entry.add_to_hass(hass)
return config_entry
@pytest.fixture(name="patch_renault_account")
async def patch_renault_account(hass: HomeAssistant) -> RenaultAccount:
"""Create a Renault account."""
renault_account = RenaultAccount(
MOCK_ACCOUNT_ID,
websession=aiohttp_client.async_get_clientsession(hass),
)
with patch("renault_api.renault_session.RenaultSession.login"), patch(
"renault_api.renault_client.RenaultClient.get_api_account",
return_value=renault_account,
):
yield renault_account
@pytest.fixture(name="patch_get_vehicles")
def patch_get_vehicles(vehicle_type: str):
"""Mock fixtures."""
with patch(
"renault_api.renault_account.RenaultAccount.get_vehicles",
return_value=(
schemas.KamereonVehiclesResponseSchema.loads(
load_fixture(f"renault/vehicle_{vehicle_type}.json")
)
),
):
yield
def _get_fixtures(vehicle_type: str) -> MappingProxyType:
"""Create a vehicle proxy for testing."""
mock_vehicle = MOCK_VEHICLES.get(vehicle_type, {"endpoints": {}})
return {
"battery_status": schemas.KamereonVehicleDataResponseSchema.loads(
load_fixture(f"renault/{mock_vehicle['endpoints']['battery_status']}")
if "battery_status" in mock_vehicle["endpoints"]
else load_fixture("renault/no_data.json")
).get_attributes(schemas.KamereonVehicleBatteryStatusDataSchema),
"charge_mode": schemas.KamereonVehicleDataResponseSchema.loads(
load_fixture(f"renault/{mock_vehicle['endpoints']['charge_mode']}")
if "charge_mode" in mock_vehicle["endpoints"]
else load_fixture("renault/no_data.json")
).get_attributes(schemas.KamereonVehicleChargeModeDataSchema),
"cockpit": schemas.KamereonVehicleDataResponseSchema.loads(
load_fixture(f"renault/{mock_vehicle['endpoints']['cockpit']}")
if "cockpit" in mock_vehicle["endpoints"]
else load_fixture("renault/no_data.json")
).get_attributes(schemas.KamereonVehicleCockpitDataSchema),
"hvac_status": schemas.KamereonVehicleDataResponseSchema.loads(
load_fixture(f"renault/{mock_vehicle['endpoints']['hvac_status']}")
if "hvac_status" in mock_vehicle["endpoints"]
else load_fixture("renault/no_data.json")
).get_attributes(schemas.KamereonVehicleHvacStatusDataSchema),
"location": schemas.KamereonVehicleDataResponseSchema.loads(
load_fixture(f"renault/{mock_vehicle['endpoints']['location']}")
if "location" in mock_vehicle["endpoints"]
else load_fixture("renault/no_data.json")
).get_attributes(schemas.KamereonVehicleLocationDataSchema),
"lock_status": schemas.KamereonVehicleDataResponseSchema.loads(
load_fixture(f"renault/{mock_vehicle['endpoints']['lock_status']}")
if "lock_status" in mock_vehicle["endpoints"]
else load_fixture("renault/no_data.json")
).get_attributes(schemas.KamereonVehicleLockStatusDataSchema),
}
@pytest.fixture(name="fixtures_with_data")
def patch_fixtures_with_data(vehicle_type: str):
"""Mock fixtures."""
mock_fixtures = _get_fixtures(vehicle_type)
with patch(
"renault_api.renault_vehicle.RenaultVehicle.get_battery_status",
return_value=mock_fixtures["battery_status"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_charge_mode",
return_value=mock_fixtures["charge_mode"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_cockpit",
return_value=mock_fixtures["cockpit"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_hvac_status",
return_value=mock_fixtures["hvac_status"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_location",
return_value=mock_fixtures["location"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_lock_status",
return_value=mock_fixtures["lock_status"],
):
yield
@pytest.fixture(name="fixtures_with_no_data")
def patch_fixtures_with_no_data():
"""Mock fixtures."""
mock_fixtures = _get_fixtures("")
with patch(
"renault_api.renault_vehicle.RenaultVehicle.get_battery_status",
return_value=mock_fixtures["battery_status"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_charge_mode",
return_value=mock_fixtures["charge_mode"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_cockpit",
return_value=mock_fixtures["cockpit"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_hvac_status",
return_value=mock_fixtures["hvac_status"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_location",
return_value=mock_fixtures["location"],
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_lock_status",
return_value=mock_fixtures["lock_status"],
):
yield
@contextlib.contextmanager
def _patch_fixtures_with_side_effect(side_effect: Any):
"""Mock fixtures."""
with patch(
"renault_api.renault_vehicle.RenaultVehicle.get_battery_status",
side_effect=side_effect,
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_charge_mode",
side_effect=side_effect,
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_cockpit",
side_effect=side_effect,
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_hvac_status",
side_effect=side_effect,
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_location",
side_effect=side_effect,
), patch(
"renault_api.renault_vehicle.RenaultVehicle.get_lock_status",
side_effect=side_effect,
):
yield
@pytest.fixture(name="fixtures_with_access_denied_exception")
def patch_fixtures_with_access_denied_exception():
"""Mock fixtures."""
access_denied_exception = exceptions.AccessDeniedException(
"err.func.403",
"Access is denied for this resource",
)
with _patch_fixtures_with_side_effect(access_denied_exception):
yield
@pytest.fixture(name="fixtures_with_invalid_upstream_exception")
def patch_fixtures_with_invalid_upstream_exception():
"""Mock fixtures."""
invalid_upstream_exception = exceptions.InvalidUpstreamException(
"err.tech.500",
"Invalid response from the upstream server (The request sent to the GDC is erroneous) ; 502 Bad Gateway",
)
with _patch_fixtures_with_side_effect(invalid_upstream_exception):
yield
@pytest.fixture(name="fixtures_with_not_supported_exception")
def patch_fixtures_with_not_supported_exception():
"""Mock fixtures."""
not_supported_exception = exceptions.NotSupportedException(
"err.tech.501",
"This feature is not technically supported by this gateway",
)
with _patch_fixtures_with_side_effect(not_supported_exception):
yield