diff --git a/requirements_test.txt b/requirements_test.txt index 1c74712..5006b51 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,2 +1,2 @@ -r requirements_dev.txt -pytest-homeassistant-custom-component==0.2.1 +pytest-homeassistant-custom-component==0.3.0 diff --git a/tests/__init__.py b/tests/__init__.py index b621d7d..b79c361 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1,113 @@ """Tests for the Renault integration.""" +from datetime import timedelta +from unittest.mock import patch + +from homeassistant.config_entries import CONN_CLASS_CLOUD_POLL +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.helpers import aiohttp_client +from pytest_homeassistant_custom_component.common import MockConfigEntry, load_fixture +from renault_api.kamereon import models, schemas +from renault_api.renault_vehicle import RenaultVehicle + +from custom_components.renault.const import ( + CONF_KAMEREON_ACCOUNT_ID, + CONF_LOCALE, + DOMAIN, +) +from custom_components.renault.renault_vehicle import RenaultVehicleProxy + +from .const import MOCK_VEHICLES + + +async def setup_renault_integration(hass): + """Create the Renault integration.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + source="user", + data={ + CONF_LOCALE: "fr_FR", + CONF_USERNAME: "email@test.com", + CONF_PASSWORD: "test", + CONF_KAMEREON_ACCOUNT_ID: "account_id_2", + }, + unique_id="account_id_2", + connection_class=CONN_CLASS_CLOUD_POLL, + options={}, + entry_id="1", + ) + config_entry.add_to_hass(hass) + + with patch( + "custom_components.renault.RenaultHub.attempt_login", return_value=True + ), patch("custom_components.renault.RenaultHub.async_initialise"): + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + return config_entry + + +async def create_vehicle_proxy(hass, vehicle_type: str) -> RenaultVehicleProxy: + """Create a vehicle proxy for testing.""" + mock_vehicle = MOCK_VEHICLES[vehicle_type] + mock_get_cockpit = schemas.KamereonVehicleDataResponseSchema.loads( + load_fixture(mock_vehicle["endpoints"]["cockpit"]) + if "cockpit" in mock_vehicle["endpoints"] + else "{}" + ).get_attributes(schemas.KamereonVehicleCockpitDataSchema) + mock_get_hvac_status = schemas.KamereonVehicleDataResponseSchema.loads( + load_fixture(mock_vehicle["endpoints"]["hvac_status"]) + if "hvac_status" in mock_vehicle["endpoints"] + else "{}" + ).get_attributes(schemas.KamereonVehicleHvacStatusDataSchema) + mock_get_battery_status = schemas.KamereonVehicleDataResponseSchema.loads( + load_fixture(mock_vehicle["endpoints"]["battery_status"]) + if "battery_status" in mock_vehicle["endpoints"] + else "{}" + ).get_attributes(schemas.KamereonVehicleBatteryStatusDataSchema) + mock_get_charge_mode = schemas.KamereonVehicleDataResponseSchema.loads( + load_fixture(mock_vehicle["endpoints"]["charge_mode"]) + if "charge_mode" in mock_vehicle["endpoints"] + else "{}" + ).get_attributes(schemas.KamereonVehicleChargeModeDataSchema) + mock_get_location = schemas.KamereonVehicleDataResponseSchema.loads( + load_fixture(mock_vehicle["endpoints"]["location"]) + if "location" in mock_vehicle["endpoints"] + else "{}" + ).get_attributes(schemas.KamereonVehicleLocationDataSchema) + + vehicles_response: models.KamereonVehiclesResponse = ( + schemas.KamereonVehiclesResponseSchema.loads( + load_fixture(f"vehicle_{vehicle_type}.json") + ) + ) + vehicle_details = vehicles_response.vehicleLinks[0].vehicleDetails + vehicle = RenaultVehicle( + vehicles_response.accountId, + vehicle_details.vin, + websession=aiohttp_client.async_get_clientsession(hass), + ) + + vehicle_proxy = RenaultVehicleProxy( + hass, vehicle, vehicle_details, timedelta(seconds=300), False + ) + with patch( + "custom_components.renault.renault_vehicle.RenaultVehicleProxy.endpoint_available", + side_effect=mock_vehicle["endpoints_available"], + ), patch( + "custom_components.renault.renault_vehicle.RenaultVehicleProxy.get_cockpit", + return_value=mock_get_cockpit, + ), patch( + "custom_components.renault.renault_vehicle.RenaultVehicleProxy.get_hvac_status", + return_value=mock_get_hvac_status, + ), patch( + "custom_components.renault.renault_vehicle.RenaultVehicleProxy.get_battery_status", + return_value=mock_get_battery_status, + ), patch( + "custom_components.renault.renault_vehicle.RenaultVehicleProxy.get_charge_mode", + return_value=mock_get_charge_mode, + ), patch( + "custom_components.renault.renault_vehicle.RenaultVehicleProxy.get_location", + return_value=mock_get_location, + ): + await vehicle_proxy.async_initialise() + return vehicle_proxy diff --git a/tests/const.py b/tests/const.py index 81d1881..9611c65 100644 --- a/tests/const.py +++ b/tests/const.py @@ -1,7 +1,37 @@ """Constants for the Renault integration tests.""" -from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.components.binary_sensor import ( + DEVICE_CLASS_BATTERY_CHARGING, + DEVICE_CLASS_PLUG, + DOMAIN as BINARY_SENSOR_DOMAIN, +) +from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN +from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN +from homeassistant.const import ( + CONF_PASSWORD, + CONF_USERNAME, + DEVICE_CLASS_BATTERY, + DEVICE_CLASS_ENERGY, + DEVICE_CLASS_TEMPERATURE, + LENGTH_KILOMETERS, + PERCENTAGE, + POWER_KILO_WATT, + STATE_NOT_HOME, + STATE_OFF, + STATE_ON, + STATE_UNKNOWN, + TEMP_CELSIUS, + TIME_MINUTES, + VOLUME_LITERS, +) -from custom_components.renault.const import CONF_KAMEREON_ACCOUNT_ID, CONF_LOCALE +from custom_components.renault.const import ( + CONF_KAMEREON_ACCOUNT_ID, + CONF_LOCALE, + DEVICE_CLASS_CHARGE_MODE, + DEVICE_CLASS_CHARGE_STATE, + DEVICE_CLASS_PLUG_STATE, + DOMAIN, +) # Mock config data to be used across multiple tests MOCK_CONFIG = { @@ -10,3 +40,348 @@ CONF_KAMEREON_ACCOUNT_ID: "account_id_1", CONF_LOCALE: "fr_FR", } + +MOCK_VEHICLES = { + "zoe_40": { + "expected_device": { + "identifiers": {(DOMAIN, "VF1AAAAA555777999")}, + "manufacturer": "Renault", + "model": "Zoe", + "name": "REG-NUMBER", + "sw_version": "X101VE", + }, + "endpoints_available": [True, True, True, True, False], + "endpoints": { + "cockpit": "cockpit_ev.json", + "hvac_status": "hvac_status.json", + "battery_status": "battery_status_charging.json", + "charge_mode": "charge_mode.json", + }, + SENSOR_DOMAIN: [ + { + "entity_id": "sensor.vf1aaaaa555777999_battery_autonomy", + "unique_id": "vf1aaaaa555777999_battery_autonomy", + "result": "141", + "unit": LENGTH_KILOMETERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_battery_level", + "unique_id": "vf1aaaaa555777999_battery_level", + "result": "60", + "unit": PERCENTAGE, + "class": DEVICE_CLASS_BATTERY, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_battery_temperature", + "unique_id": "vf1aaaaa555777999_battery_temperature", + "result": "20", + "unit": TEMP_CELSIUS, + "class": DEVICE_CLASS_TEMPERATURE, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_charge_mode", + "unique_id": "vf1aaaaa555777999_charge_mode", + "result": "always", + "class": DEVICE_CLASS_CHARGE_MODE, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_charge_state", + "unique_id": "vf1aaaaa555777999_charge_state", + "result": "charge_in_progress", + "class": DEVICE_CLASS_CHARGE_STATE, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_charging_power", + "unique_id": "vf1aaaaa555777999_charging_power", + "result": "0.027", + "unit": POWER_KILO_WATT, + "class": DEVICE_CLASS_ENERGY, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_charging_remaining_time", + "unique_id": "vf1aaaaa555777999_charging_remaining_time", + "result": "145", + "unit": TIME_MINUTES, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_mileage", + "unique_id": "vf1aaaaa555777999_mileage", + "result": "49114", + "unit": LENGTH_KILOMETERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_outside_temperature", + "unique_id": "vf1aaaaa555777999_outside_temperature", + "result": "8.0", + "unit": TEMP_CELSIUS, + "class": DEVICE_CLASS_TEMPERATURE, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_plug_state", + "unique_id": "vf1aaaaa555777999_plug_state", + "result": "plugged", + "class": DEVICE_CLASS_PLUG_STATE, + }, + ], + BINARY_SENSOR_DOMAIN: [ + { + "entity_id": "binary_sensor.vf1aaaaa555777999_plugged_in", + "unique_id": "vf1aaaaa555777999_plugged_in", + "result": STATE_ON, + "class": DEVICE_CLASS_PLUG, + }, + { + "entity_id": "binary_sensor.vf1aaaaa555777999_charging", + "unique_id": "vf1aaaaa555777999_charging", + "result": STATE_ON, + "class": DEVICE_CLASS_BATTERY_CHARGING, + }, + ], + DEVICE_TRACKER_DOMAIN: [], + }, + "zoe_50": { + "expected_device": { + "identifiers": {(DOMAIN, "VF1AAAAA555777999")}, + "manufacturer": "Renault", + "model": "Zoe", + "name": "REG-NUMBER", + "sw_version": "X102VE", + }, + "endpoints_available": [True, False, True, True, True], + "endpoints": { + "cockpit": "cockpit_ev.json", + "battery_status": "battery_status_not_charging.json", + "charge_mode": "charge_mode.json", + "location": "location.json", + }, + SENSOR_DOMAIN: [ + { + "entity_id": "sensor.vf1aaaaa555777999_battery_autonomy", + "unique_id": "vf1aaaaa555777999_battery_autonomy", + "result": "128", + "unit": LENGTH_KILOMETERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_battery_level", + "unique_id": "vf1aaaaa555777999_battery_level", + "result": "50", + "unit": PERCENTAGE, + "class": DEVICE_CLASS_BATTERY, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_battery_temperature", + "unique_id": "vf1aaaaa555777999_battery_temperature", + "result": STATE_UNKNOWN, + "unit": TEMP_CELSIUS, + "class": DEVICE_CLASS_TEMPERATURE, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_charge_mode", + "unique_id": "vf1aaaaa555777999_charge_mode", + "result": "always", + "class": DEVICE_CLASS_CHARGE_MODE, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_charge_state", + "unique_id": "vf1aaaaa555777999_charge_state", + "result": "charge_error", + "class": DEVICE_CLASS_CHARGE_STATE, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_charging_power", + "unique_id": "vf1aaaaa555777999_charging_power", + "result": STATE_UNKNOWN, + "unit": POWER_KILO_WATT, + "class": DEVICE_CLASS_ENERGY, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_charging_remaining_time", + "unique_id": "vf1aaaaa555777999_charging_remaining_time", + "result": STATE_UNKNOWN, + "unit": TIME_MINUTES, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_mileage", + "unique_id": "vf1aaaaa555777999_mileage", + "result": "49114", + "unit": LENGTH_KILOMETERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777999_plug_state", + "unique_id": "vf1aaaaa555777999_plug_state", + "result": "unplugged", + "class": DEVICE_CLASS_PLUG_STATE, + }, + ], + BINARY_SENSOR_DOMAIN: [ + { + "entity_id": "binary_sensor.vf1aaaaa555777999_plugged_in", + "unique_id": "vf1aaaaa555777999_plugged_in", + "result": STATE_OFF, + "class": DEVICE_CLASS_PLUG, + }, + { + "entity_id": "binary_sensor.vf1aaaaa555777999_charging", + "unique_id": "vf1aaaaa555777999_charging", + "result": STATE_OFF, + "class": DEVICE_CLASS_BATTERY_CHARGING, + }, + ], + DEVICE_TRACKER_DOMAIN: [ + { + "entity_id": "device_tracker.vf1aaaaa555777999_location", + "unique_id": "vf1aaaaa555777999_location", + "result": STATE_NOT_HOME, + } + ], + }, + "captur_phev": { + "expected_device": { + "identifiers": {(DOMAIN, "VF1AAAAA555777123")}, + "manufacturer": "Renault", + "model": "Captur ii", + "name": "REG-NUMBER", + "sw_version": "XJB1SU", + }, + "endpoints_available": [True, False, True, True, True], + "endpoints": { + "cockpit": "cockpit_fuel.json", + "battery_status": "battery_status_charging.json", + "charge_mode": "charge_mode.json", + "location": "location.json", + }, + SENSOR_DOMAIN: [ + { + "entity_id": "sensor.vf1aaaaa555777123_battery_autonomy", + "unique_id": "vf1aaaaa555777123_battery_autonomy", + "result": "141", + "unit": LENGTH_KILOMETERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_battery_level", + "unique_id": "vf1aaaaa555777123_battery_level", + "result": "60", + "unit": PERCENTAGE, + "class": DEVICE_CLASS_BATTERY, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_battery_temperature", + "unique_id": "vf1aaaaa555777123_battery_temperature", + "result": "20", + "unit": TEMP_CELSIUS, + "class": DEVICE_CLASS_TEMPERATURE, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_charge_mode", + "unique_id": "vf1aaaaa555777123_charge_mode", + "result": "always", + "class": DEVICE_CLASS_CHARGE_MODE, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_charge_state", + "unique_id": "vf1aaaaa555777123_charge_state", + "result": "charge_in_progress", + "class": DEVICE_CLASS_CHARGE_STATE, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_charging_power", + "unique_id": "vf1aaaaa555777123_charging_power", + "result": "27.0", + "unit": POWER_KILO_WATT, + "class": DEVICE_CLASS_ENERGY, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_charging_remaining_time", + "unique_id": "vf1aaaaa555777123_charging_remaining_time", + "result": "145", + "unit": TIME_MINUTES, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_fuel_autonomy", + "unique_id": "vf1aaaaa555777123_fuel_autonomy", + "result": "35", + "unit": LENGTH_KILOMETERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_fuel_quantity", + "unique_id": "vf1aaaaa555777123_fuel_quantity", + "result": "3", + "unit": VOLUME_LITERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_mileage", + "unique_id": "vf1aaaaa555777123_mileage", + "result": "5567", + "unit": LENGTH_KILOMETERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_plug_state", + "unique_id": "vf1aaaaa555777123_plug_state", + "result": "plugged", + "class": DEVICE_CLASS_PLUG_STATE, + }, + ], + BINARY_SENSOR_DOMAIN: [ + { + "entity_id": "binary_sensor.vf1aaaaa555777123_plugged_in", + "unique_id": "vf1aaaaa555777123_plugged_in", + "result": STATE_ON, + "class": DEVICE_CLASS_PLUG, + }, + { + "entity_id": "binary_sensor.vf1aaaaa555777123_charging", + "unique_id": "vf1aaaaa555777123_charging", + "result": STATE_ON, + "class": DEVICE_CLASS_BATTERY_CHARGING, + }, + ], + DEVICE_TRACKER_DOMAIN: [ + { + "entity_id": "device_tracker.vf1aaaaa555777123_location", + "unique_id": "vf1aaaaa555777123_location", + "result": STATE_NOT_HOME, + } + ], + }, + "captur_fuel": { + "expected_device": { + "identifiers": {(DOMAIN, "VF1AAAAA555777123")}, + "manufacturer": "Renault", + "model": "Captur ii", + "name": "REG-NUMBER", + "sw_version": "XJB1SU", + }, + "endpoints_available": [True, False, True], + "endpoints": { + "cockpit": "cockpit_fuel.json", + "location": "location.json", + }, + SENSOR_DOMAIN: [ + { + "entity_id": "sensor.vf1aaaaa555777123_fuel_autonomy", + "unique_id": "vf1aaaaa555777123_fuel_autonomy", + "result": "35", + "unit": LENGTH_KILOMETERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_fuel_quantity", + "unique_id": "vf1aaaaa555777123_fuel_quantity", + "result": "3", + "unit": VOLUME_LITERS, + }, + { + "entity_id": "sensor.vf1aaaaa555777123_mileage", + "unique_id": "vf1aaaaa555777123_mileage", + "result": "5567", + "unit": LENGTH_KILOMETERS, + }, + ], + DEVICE_TRACKER_DOMAIN: [ + { + "entity_id": "device_tracker.vf1aaaaa555777123_location", + "unique_id": "vf1aaaaa555777123_location", + "result": STATE_NOT_HOME, + } + ], + }, +} diff --git a/tests/fixtures/battery_status_charging.json b/tests/fixtures/battery_status_charging.json new file mode 100644 index 0000000..dbde459 --- /dev/null +++ b/tests/fixtures/battery_status_charging.json @@ -0,0 +1,18 @@ +{ + "data": { + "type": "Car", + "id": "VF1AAAAA555777999", + "attributes": { + "timestamp": "2020-01-12T21:40:16Z", + "batteryLevel": 60, + "batteryTemperature": 20, + "batteryAutonomy": 141, + "batteryCapacity": 0, + "batteryAvailableEnergy": 31, + "plugStatus": 1, + "chargingStatus": 1.0, + "chargingRemainingTime": 145, + "chargingInstantaneousPower": 27 + } + } +} diff --git a/tests/fixtures/battery_status_not_charging.json b/tests/fixtures/battery_status_not_charging.json new file mode 100644 index 0000000..750d008 --- /dev/null +++ b/tests/fixtures/battery_status_not_charging.json @@ -0,0 +1,15 @@ +{ + "data": { + "type": "Car", + "id": "VF1AAAAA555777999", + "attributes": { + "timestamp": "2020-11-17T09:06:48+01:00", + "batteryLevel": 50, + "batteryAutonomy": 128, + "batteryCapacity": 0, + "batteryAvailableEnergy": 0, + "plugStatus": 0, + "chargingStatus": -1.0 + } + } +} diff --git a/tests/fixtures/charge_mode.json b/tests/fixtures/charge_mode.json new file mode 100644 index 0000000..6f146a2 --- /dev/null +++ b/tests/fixtures/charge_mode.json @@ -0,0 +1,7 @@ +{ + "data": { + "type": "Car", + "id": "VF1AAAAA555777999", + "attributes": { "chargeMode": "always" } + } +} diff --git a/tests/fixtures/cockpit_ev.json b/tests/fixtures/cockpit_ev.json new file mode 100644 index 0000000..c5a390f --- /dev/null +++ b/tests/fixtures/cockpit_ev.json @@ -0,0 +1,9 @@ +{ + "data": { + "type": "Car", + "id": "VF1AAAAA555777999", + "attributes": { + "totalMileage": 49114.27 + } + } +} diff --git a/tests/fixtures/cockpit_fuel.json b/tests/fixtures/cockpit_fuel.json new file mode 100644 index 0000000..575a423 --- /dev/null +++ b/tests/fixtures/cockpit_fuel.json @@ -0,0 +1,11 @@ +{ + "data": { + "type": "Car", + "id": "VF1AAAAA555777123", + "attributes": { + "fuelAutonomy": 35.0, + "fuelQuantity": 3.0, + "totalMileage": 5566.78 + } + } +} diff --git a/tests/fixtures/hvac_status.json b/tests/fixtures/hvac_status.json new file mode 100644 index 0000000..f48cbae --- /dev/null +++ b/tests/fixtures/hvac_status.json @@ -0,0 +1,7 @@ +{ + "data": { + "type": "Car", + "id": "VF1AAAAA555777999", + "attributes": { "externalTemperature": 8.0, "hvacStatus": "off" } + } +} diff --git a/tests/fixtures/location.json b/tests/fixtures/location.json new file mode 100644 index 0000000..bae4474 --- /dev/null +++ b/tests/fixtures/location.json @@ -0,0 +1,11 @@ +{ + "data": { + "type": "Car", + "id": "VF1AAAAA555777999", + "attributes": { + "gpsLatitude": 48.1234567, + "gpsLongitude": 11.1234567, + "lastUpdateTime": "2020-02-18T16:58:38Z" + } + } +} diff --git a/tests/fixtures/vehicle_captur_fuel.json b/tests/fixtures/vehicle_captur_fuel.json new file mode 100644 index 0000000..3aa854c --- /dev/null +++ b/tests/fixtures/vehicle_captur_fuel.json @@ -0,0 +1,108 @@ +{ + "accountId": "account-id-1", + "country": "LU", + "vehicleLinks": [ + { + "brand": "RENAULT", + "vin": "VF1AAAAA555777123", + "status": "ACTIVE", + "linkType": "USER", + "garageBrand": "RENAULT", + "mileage": 346, + "startDate": "2020-06-12", + "createdDate": "2020-06-12T15:02:00.555432Z", + "lastModifiedDate": "2020-06-15T06:21:43.762467Z", + "cancellationReason": {}, + "connectedDriver": { + "role": "MAIN_DRIVER", + "createdDate": "2020-06-15T06:20:39.107794Z", + "lastModifiedDate": "2020-06-15T06:20:39.107794Z" + }, + "vehicleDetails": { + "vin": "VF1AAAAA555777123", + "engineType": "H5H", + "engineRatio": "470", + "modelSCR": "CP1", + "deliveryCountry": { + "code": "BE", + "label": "BELGIQUE" + }, + "family": { + "code": "XJB", + "label": "FAMILLE B+X OVER", + "group": "007" + }, + "tcu": { + "code": "AIVCT", + "label": "AVEC BOITIER CONNECT AIVC", + "group": "E70" + }, + "navigationAssistanceLevel": { + "code": "", + "label": "", + "group": "" + }, + "battery": { + "code": "SANBAT", + "label": "SANS BATTERIE", + "group": "968" + }, + "radioType": { + "code": "NA406", + "label": "A-IVIMINDL, 2BO + 2BI + 2T, MICRO-DOUBLE, FM1/DAB+FM2", + "group": "425" + }, + "registrationCountry": { + "code": "BE" + }, + "brand": { + "label": "RENAULT" + }, + "model": { + "code": "XJB1SU", + "label": "CAPTUR II", + "group": "971" + }, + "gearbox": { + "code": "BVA7", + "label": "BOITE DE VITESSE AUTOMATIQUE 7 RAPPORTS", + "group": "427" + }, + "version": { + "code": "ITAMFHA 6TH" + }, + "energy": { + "code": "ESS", + "label": "ESSENCE", + "group": "019" + }, + "registrationNumber": "REG-NUMBER", + "vcd": "ADR00/DLIGM2/PGPRT2/FEUAR3/CDVIT1/SKTPOU/SKTPGR/SSCCPC/SSPREM/FDIU2/MAPSTD/RCALL/MET04/DANGMO/ECOMOD/SSRCAR/AIVCT/AVGSI/TPRPE/TSGNE/2TON/ITPK7/MLEXP1/SPERTA/SSPERG/SPERTP/VOLCHA/SREACT/AVOSP1/SWALBO/DWGE01/AVC1A/1234Y/AEBS07/PRAHL/AVCAM/STANDA/XJB/HJB/EA3/MF/ESS/DG/TEMP/TR4X2/AFURGE/RVDIST/ABS/SBARTO/CA02/TOPAN/PBNCH/LAC/VSTLAR/CPE/RET04/2RVLG/RALU17/CEAVRH/AIRBA2/SERIE/DRA/DRAP05/HARM01/ATAR03/SGAV02/SGAR02/BIXPE/BANAL/KM/TPRM3/AVREPL/SSDECA/SFIRBA/ABLAVI/ESPHSA/FPAS2/ALEVA/SCACBA/SOP03C/SSADPC/STHPLG/SKTGRV/VLCUIR/RETIN2/TRSEV1/REPNTC/LVAVIP/LVAREI/SASURV/KTGREP/SGACHA/BEL01/APL03/FSTPO/ALOUC5/CMAR3P/FIPOU2/NA406/BVA7/ECLHB4/RDIF10/PNSTRD/ISOFIX/ENPH01/HRGM01/SANFLT/CSRGAC/SANACF/SDPCLV/TLRP00/SPRODI/SAN613/AVFAP/AIRBDE/CHC03/E06T/SAN806/SSPTLP/SANCML/SSFLEX/SDRQAR/SEXTIN/M2019/PHAS1/SPRTQT/SAN913/STHABT/SSTYAD/HYB01/SSCABA/SANBAT/VEC012/XJB1SU/SSNBT/H5H", + "assets": [ + { + "assetType": "PICTURE", + "renditions": [ + { + "resolutionType": "ONE_MYRENAULT_LARGE", + "url": "https: //3dv2.renault.com/ImageFromBookmark?configuration=ADR00%2FDLIGM2%2FPGPRT2%2FFEUAR3%2FCDVIT1%2FSSCCPC%2FRCALL%2FMET04%2FDANGMO%2FSSRCAR%2FAVGSI%2FITPK7%2FMLEXP1%2FSPERTA%2FSSPERG%2FSPERTP%2FVOLCHA%2FSREACT%2FDWGE01%2FAVCAM%2FHJB%2FEA3%2FESS%2FDG%2FTEMP%2FTR4X2%2FRVDIST%2FSBARTO%2FCA02%2FTOPAN%2FPBNCH%2FVSTLAR%2FCPE%2FRET04%2FRALU17%2FDRA%2FDRAP05%2FHARM01%2FBIXPE%2FKM%2FSSDECA%2FESPHSA%2FFPAS2%2FALEVA%2FSOP03C%2FSSADPC%2FVLCUIR%2FRETIN2%2FREPNTC%2FLVAVIP%2FLVAREI%2FSGACHA%2FALOUC5%2FNA406%2FBVA7%2FECLHB4%2FRDIF10%2FCSRGAC%2FSANACF%2FTLRP00%2FAIRBDE%2FCHC03%2FSSPTLP%2FSPRTQT%2FSAN913%2FHYB01%2FH5H&databaseId=3e814da7-766d-4039-ac69-f001a1f738c8&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_LARGE" + }, + { + "resolutionType": "ONE_MYRENAULT_SMALL", + "url": "https: //3dv2.renault.com/ImageFromBookmark?configuration=ADR00%2FDLIGM2%2FPGPRT2%2FFEUAR3%2FCDVIT1%2FSSCCPC%2FRCALL%2FMET04%2FDANGMO%2FSSRCAR%2FAVGSI%2FITPK7%2FMLEXP1%2FSPERTA%2FSSPERG%2FSPERTP%2FVOLCHA%2FSREACT%2FDWGE01%2FAVCAM%2FHJB%2FEA3%2FESS%2FDG%2FTEMP%2FTR4X2%2FRVDIST%2FSBARTO%2FCA02%2FTOPAN%2FPBNCH%2FVSTLAR%2FCPE%2FRET04%2FRALU17%2FDRA%2FDRAP05%2FHARM01%2FBIXPE%2FKM%2FSSDECA%2FESPHSA%2FFPAS2%2FALEVA%2FSOP03C%2FSSADPC%2FVLCUIR%2FRETIN2%2FREPNTC%2FLVAVIP%2FLVAREI%2FSGACHA%2FALOUC5%2FNA406%2FBVA7%2FECLHB4%2FRDIF10%2FCSRGAC%2FSANACF%2FTLRP00%2FAIRBDE%2FCHC03%2FSSPTLP%2FSPRTQT%2FSAN913%2FHYB01%2FH5H&databaseId=3e814da7-766d-4039-ac69-f001a1f738c8&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_SMALL_V2" + } + ] + } + ], + "yearsOfMaintenance": 12, + "connectivityTechnology": "NONE", + "easyConnectStore": false, + "electrical": false, + "rlinkStore": false, + "deliveryDate": "2020-06-17", + "retrievedFromDhs": false, + "engineEnergyType": "OTHER", + "radioCode": "1234" + } + } + ] +} diff --git a/tests/fixtures/vehicle_captur_phev.json b/tests/fixtures/vehicle_captur_phev.json new file mode 100644 index 0000000..03066c8 --- /dev/null +++ b/tests/fixtures/vehicle_captur_phev.json @@ -0,0 +1,110 @@ +{ + "accountId": "account-id-2", + "country": "IT", + "vehicleLinks": [ + { + "brand": "RENAULT", + "vin": "VF1AAAAA555777123", + "status": "ACTIVE", + "linkType": "OWNER", + "garageBrand": "RENAULT", + "startDate": "2020-10-07", + "createdDate": "2020-10-07T09:17:44.692802Z", + "lastModifiedDate": "2021-03-28T10:44:01.139649Z", + "ownershipStartDate": "2020-09-30", + "cancellationReason": {}, + "connectedDriver": { + "role": "MAIN_DRIVER", + "createdDate": "2020-10-08T17:36:39.445523Z", + "lastModifiedDate": "2020-10-08T17:36:39.445523Z" + }, + "vehicleDetails": { + "vin": "VF1AAAAA555777123", + "registrationDate": "2020-09-30", + "firstRegistrationDate": "2020-09-30", + "engineType": "H4M", + "engineRatio": "630", + "modelSCR": "", + "deliveryCountry": { + "code": "IT", + "label": "ITALY" + }, + "family": { + "code": "XJB", + "label": "B+X OVER FAMILY", + "group": "007" + }, + "tcu": { + "code": "AIVCT", + "label": "WITH AIVC CONNECTION UNIT", + "group": "E70" + }, + "navigationAssistanceLevel": { + "code": "", + "label": "", + "group": "" + }, + "battery": { + "code": "BT9AE1", + "label": "BATTERY BT9AE1", + "group": "968" + }, + "radioType": { + "code": "NA418", + "label": "FULL NAV DAB ETH - AUDI", + "group": "425" + }, + "registrationCountry": { + "code": "IT" + }, + "brand": { + "label": "RENAULT" + }, + "model": { + "code": "XJB1SU", + "label": "CAPTUR II", + "group": "971" + }, + "gearbox": { + "code": "BVH4", + "label": "HYBRID 4 SPEED GEARBOX", + "group": "427" + }, + "version": { + "code": "ITAMMHH 6UP" + }, + "energy": { + "code": "ESS", + "label": "PETROL", + "group": "019" + }, + "registrationNumber": "REG-NUMBER", + "vcd": "STANDA/XJB/HJB/EA3/MM/ESS/DG/TEMP/TR4X2/AFURGE/RV/ABS/SBARTO/CA02/TN/PBNCH/LAC/VT/CPE/RET04/2RVLG/RALU17/CEAVRH/AIRBA2/SERIE/DRA/DRAP05/HARM01/ATAR03/SGAV01/SGAR02/BIYPC/BANAL/KM/TPRM3/AVREPL/SSDECA/SFIRBA/ABLAVI/ESPHSA/FPAS2/ALEVA/CACBL3/SOP03C/SSADPC/STHPLG/SKTGRV/VLCUIR/RETRCR/TRSEV1/REPNTC/LVAVIP/LVAREI/SASURV/KTGREP/SGSCHA/ITA01/APL03/FSTPO/ALOUC5/PART01/CMAR3P/FIPOU2/NA418/BVH4/ECLHB4/RDIF10/PNSTRD/ISOFIX/ENPH01/HRGM01/SANFLT/CSRFLY/SANACF/SDPCLV/TLRP00/SPRODI/SAN613/AVFAP/AIRBDE/CHC03/E06U/SAN806/SSPTLP/SANCML/SSFLEX/SDRQAR/SEXTIN/M2019/PHAS1/SPRTQT/SAN913/STHABT/5DHS/HYB06/010KWH/BT9AE1/VEC237/XJB1SU/NBT018/H4M/NOADR/DLIGM2/PGPRT2/FEUAR3/SCDVIT/SKTPOU/SKTPGR/SSCCPC/SSPREM/FDIU2/MAPSTD/RCALL/MET05/SDANGM/ECOMOD/SSRCAR/AIVCT/AVGSI/TPQNW/TSGNE/2TON/ITPK4/MLEXP1/SPERTA/SSPERG/SPERTP/VOLNCH/SREACT/AVTSR1/SWALBO/DWGE01/AVC1A/VSPTA/1234Y/AEBS07/PRAHL/RRCAM", + "assets": [ + { + "assetType": "PICTURE", + "renditions": [ + { + "resolutionType": "ONE_MYRENAULT_LARGE", + "url": "https://3dv2.renault.com/ImageFromBookmark?configuration=HJB%2FEA3%2FESS%2FDG%2FTEMP%2FTR4X2%2FRV%2FSBARTO%2FCA02%2FTN%2FPBNCH%2FVT%2FCPE%2FRET04%2FRALU17%2FDRA%2FDRAP05%2FHARM01%2FBIYPC%2FKM%2FSSDECA%2FESPHSA%2FFPAS2%2FALEVA%2FSOP03C%2FSSADPC%2FVLCUIR%2FRETRCR%2FREPNTC%2FLVAVIP%2FLVAREI%2FALOUC5%2FNA418%2FBVH4%2FECLHB4%2FRDIF10%2FCSRFLY%2FSANACF%2FTLRP00%2FAIRBDE%2FCHC03%2FSSPTLP%2FSPRTQT%2FSAN913%2FHYB06%2FH4M%2FNOADR%2FDLIGM2%2FPGPRT2%2FFEUAR3%2FSSCCPC%2FRCALL%2FMET05%2FSDANGM%2FSSRCAR%2FAVGSI%2FITPK4%2FMLEXP1%2FSPERTA%2FSSPERG%2FSPERTP%2FVOLNCH%2FSREACT%2FDWGE01%2FRRCAM&databaseId=b2b4fefb-d131-4f8f-9a24-4223c38bc710&bookmarkSet=CARPICKER&bookmark=EXT_34_RIGHT_FRONT&profile=HELIOS_OWNERSERVICES_LARGE" + }, + { + "resolutionType": "ONE_MYRENAULT_SMALL", + "url": "https://3dv2.renault.com/ImageFromBookmark?configuration=HJB%2FEA3%2FESS%2FDG%2FTEMP%2FTR4X2%2FRV%2FSBARTO%2FCA02%2FTN%2FPBNCH%2FVT%2FCPE%2FRET04%2FRALU17%2FDRA%2FDRAP05%2FHARM01%2FBIYPC%2FKM%2FSSDECA%2FESPHSA%2FFPAS2%2FALEVA%2FSOP03C%2FSSADPC%2FVLCUIR%2FRETRCR%2FREPNTC%2FLVAVIP%2FLVAREI%2FALOUC5%2FNA418%2FBVH4%2FECLHB4%2FRDIF10%2FCSRFLY%2FSANACF%2FTLRP00%2FAIRBDE%2FCHC03%2FSSPTLP%2FSPRTQT%2FSAN913%2FHYB06%2FH4M%2FNOADR%2FDLIGM2%2FPGPRT2%2FFEUAR3%2FSSCCPC%2FRCALL%2FMET05%2FSDANGM%2FSSRCAR%2FAVGSI%2FITPK4%2FMLEXP1%2FSPERTA%2FSSPERG%2FSPERTP%2FVOLNCH%2FSREACT%2FDWGE01%2FRRCAM&databaseId=b2b4fefb-d131-4f8f-9a24-4223c38bc710&bookmarkSet=CARPICKER&bookmark=EXT_34_RIGHT_FRONT&profile=HELIOS_OWNERSERVICES_SMALL_V2" + } + ] + } + ], + "yearsOfMaintenance": 12, + "connectivityTechnology": "NONE", + "easyConnectStore": false, + "electrical": false, + "rlinkStore": false, + "deliveryDate": "2020-09-30", + "retrievedFromDhs": false, + "engineEnergyType": "PHEV", + "radioCode": "1234" + } + } + ] +} diff --git a/tests/fixtures/vehicle_zoe_40.json b/tests/fixtures/vehicle_zoe_40.json new file mode 100644 index 0000000..ab80d58 --- /dev/null +++ b/tests/fixtures/vehicle_zoe_40.json @@ -0,0 +1,189 @@ +{ + "accountId": "account-id-1", + "country": "FR", + "vehicleLinks": [ + { + "brand": "RENAULT", + "vin": "VF1AAAAA555777999", + "status": "ACTIVE", + "linkType": "OWNER", + "garageBrand": "RENAULT", + "annualMileage": 16000, + "mileage": 26464, + "startDate": "2017-08-07", + "createdDate": "2019-05-23T21:38:16.409008Z", + "lastModifiedDate": "2020-11-17T08:41:40.497400Z", + "ownershipStartDate": "2017-08-01", + "cancellationReason": {}, + "connectedDriver": { + "role": "MAIN_DRIVER", + "createdDate": "2019-06-17T09:49:06.880627Z", + "lastModifiedDate": "2019-06-17T09:49:06.880627Z" + }, + "vehicleDetails": { + "vin": "VF1AAAAA555777999", + "registrationDate": "2017-08-01", + "firstRegistrationDate": "2017-08-01", + "engineType": "5AQ", + "engineRatio": "601", + "modelSCR": "ZOE", + "deliveryCountry": { + "code": "FR", + "label": "FRANCE" + }, + "family": { + "code": "X10", + "label": "FAMILLE X10", + "group": "007" + }, + "tcu": { + "code": "TCU0G2", + "label": "TCU VER 0 GEN 2", + "group": "E70" + }, + "navigationAssistanceLevel": { + "code": "NAV3G5", + "label": "LEVEL 3 TYPE 5 NAVIGATION", + "group": "408" + }, + "battery": { + "code": "BT4AR1", + "label": "BATTERIE BT4AR1", + "group": "968" + }, + "radioType": { + "code": "RAD37A", + "label": "RADIO 37A", + "group": "425" + }, + "registrationCountry": { + "code": "FR" + }, + "brand": { + "label": "RENAULT" + }, + "model": { + "code": "X101VE", + "label": "ZOE", + "group": "971" + }, + "gearbox": { + "code": "BVEL", + "label": "BOITE A VARIATEUR ELECTRIQUE", + "group": "427" + }, + "version": { + "code": "INT MB 10R" + }, + "energy": { + "code": "ELEC", + "label": "ELECTRIQUE", + "group": "019" + }, + "registrationNumber": "REG-NUMBER", + "vcd": "SYTINC/SKTPOU/SAND41/FDIU1/SSESM/MAPSUP/SSCALL/SAND88/SAND90/SQKDRO/SDIFPA/FACBA2/PRLEX1/SSRCAR/CABDO2/TCU0G2/SWALBO/EVTEC1/STANDA/X10/B10/EA2/MB/ELEC/DG/TEMP/TR4X2/RV/ABS/CAREG/LAC/VT003/CPE/RET03/SPROJA/RALU16/CEAVRH/AIRBA1/SERIE/DRA/DRAP08/HARM02/ATAR/TERQG/SFBANA/KM/DPRPN/AVREPL/SSDECA/ASRESP/RDAR02/ALEVA/CACBL2/SOP02C/CTHAB2/TRNOR/LVAVIP/LVAREL/SASURV/KTGREP/SGSCHA/APL03/ALOUCC/CMAR3P/NAV3G5/RAD37A/BVEL/AUTAUG/RNORM/ISOFIX/EQPEUR/HRGM01/SDPCLV/TLFRAN/SPRODI/SAN613/SSAPEX/GENEV1/ELC1/SANCML/PE2012/PHAS1/SAN913/045KWH/BT4AR1/VEC153/X101VE/NBT017/5AQ", + "assets": [ + { + "assetType": "PICTURE", + "renditions": [ + { + "resolutionType": "ONE_MYRENAULT_LARGE", + "url": "https://3dv2.renault.com/ImageFromBookmark?configuration=SKTPOU%2FPRLEX1%2FSTANDA%2FB10%2FEA2%2FDG%2FVT003%2FRET03%2FRALU16%2FDRAP08%2FHARM02%2FTERQG%2FRDAR02%2FALEVA%2FSOP02C%2FTRNOR%2FLVAVIP%2FLVAREL%2FNAV3G5%2FRAD37A%2FSDPCLV%2FTLFRAN%2FGENEV1%2FSAN913%2FBT4AR1%2FNBT017&databaseId=1d514feb-93a6-4b45-8785-e11d2a6f1864&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_LARGE" + }, + { + "resolutionType": "ONE_MYRENAULT_SMALL", + "url": "https://3dv2.renault.com/ImageFromBookmark?configuration=SKTPOU%2FPRLEX1%2FSTANDA%2FB10%2FEA2%2FDG%2FVT003%2FRET03%2FRALU16%2FDRAP08%2FHARM02%2FTERQG%2FRDAR02%2FALEVA%2FSOP02C%2FTRNOR%2FLVAVIP%2FLVAREL%2FNAV3G5%2FRAD37A%2FSDPCLV%2FTLFRAN%2FGENEV1%2FSAN913%2FBT4AR1%2FNBT017&databaseId=1d514feb-93a6-4b45-8785-e11d2a6f1864&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_SMALL_V2" + } + ] + }, + { + "assetType": "PDF", + "assetRole": "GUIDE", + "title": "PDF Guide", + "description": "", + "renditions": [ + { + "url": "https://cdn.group.renault.com/ren/gb/myr/assets/x101ve/manual.pdf.asset.pdf/1558704861676.pdf" + } + ] + }, + { + "assetType": "URL", + "assetRole": "GUIDE", + "title": "e-guide", + "description": "", + "renditions": [ + { + "url": "http://gb.e-guide.renault.com/eng/Zoe" + } + ] + }, + { + "assetType": "VIDEO", + "assetRole": "CAR", + "title": "10 Fundamentals about getting the best out of your electric vehicle", + "description": "", + "renditions": [ + { + "url": "39r6QEKcOM4" + } + ] + }, + { + "assetType": "VIDEO", + "assetRole": "CAR", + "title": "Automatic Climate Control", + "description": "", + "renditions": [ + { + "url": "Va2FnZFo_GE" + } + ] + }, + { + "assetType": "URL", + "assetRole": "CAR", + "title": "More videos", + "description": "", + "renditions": [ + { + "url": "https://www.youtube.com/watch?v=wfpCMkK1rKI" + } + ] + }, + { + "assetType": "VIDEO", + "assetRole": "CAR", + "title": "Charging the battery", + "description": "", + "renditions": [ + { + "url": "RaEad8DjUJs" + } + ] + }, + { + "assetType": "VIDEO", + "assetRole": "CAR", + "title": "Charging the battery at a station with a flap", + "description": "", + "renditions": [ + { + "url": "zJfd7fJWtr0" + } + ] + } + ], + "yearsOfMaintenance": 12, + "connectivityTechnology": "RLINK1", + "easyConnectStore": false, + "electrical": true, + "rlinkStore": false, + "deliveryDate": "2017-08-11", + "retrievedFromDhs": false, + "engineEnergyType": "ELEC", + "radioCode": "1234" + } + } + ] +} diff --git a/tests/fixtures/vehicle_zoe_50.json b/tests/fixtures/vehicle_zoe_50.json new file mode 100644 index 0000000..560b2a2 --- /dev/null +++ b/tests/fixtures/vehicle_zoe_50.json @@ -0,0 +1,161 @@ +{ + "country": "GB", + "vehicleLinks": [ + { + "preferredDealer": { + "brand": "RENAULT", + "createdDate": "2019-05-23T20:42:01.086661Z", + "lastModifiedDate": "2019-05-23T20:42:01.086662Z", + "dealerId": "dealer-id-1" + }, + "garageBrand": "RENAULT", + "vehicleDetails": { + "assets": [ + { + "assetType": "PICTURE", + "renditions": [ + { + "resolutionType": "ONE_MYRENAULT_LARGE", + "url": "https://3dv2.renault.com/ImageFromBookmark?configuration=DLIGM2%2FKITPOU%2FDANGMO%2FITPK4%2FVOLNCH%2FREACTI%2FSSAEBS%2FPRAHL%2FRRCAM%2FX10%2FB10%2FEA3%2FDG%2FCAREG%2FVSTLAR%2FRET03%2FPROJAB%2FRALU16%2FDRAP13%2F3ATRPH%2FTELNJ%2FALEVA%2FVLCUIR%2FRETRCR%2FRETC%2FLVAREL%2FSGSCHA%2FNA418%2FRDIF01%2FTL01A%2FNBT022&databaseId=a864e752-b1b9-405e-9c3e-880073e36cc9&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_LARGE" + }, + { + "resolutionType": "ONE_MYRENAULT_SMALL", + "url": "https://3dv2.renault.com/ImageFromBookmark?configuration=DLIGM2%2FKITPOU%2FDANGMO%2FITPK4%2FVOLNCH%2FREACTI%2FSSAEBS%2FPRAHL%2FRRCAM%2FX10%2FB10%2FEA3%2FDG%2FCAREG%2FVSTLAR%2FRET03%2FPROJAB%2FRALU16%2FDRAP13%2F3ATRPH%2FTELNJ%2FALEVA%2FVLCUIR%2FRETRCR%2FRETC%2FLVAREL%2FSGSCHA%2FNA418%2FRDIF01%2FTL01A%2FNBT022&databaseId=a864e752-b1b9-405e-9c3e-880073e36cc9&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_SMALL_V2" + } + ] + }, + { + "title": "PDF Guide", + "description": "", + "assetType": "PDF", + "assetRole": "GUIDE", + "renditions": [ + { + "url": "https://cdn.group.renault.com/ren/gb/myr/assets/x102ve/manual.pdf.asset.pdf/1558696740707.pdf" + } + ] + }, + { + "title": "e-guide", + "description": "", + "assetType": "URL", + "assetRole": "GUIDE", + "renditions": [ + { + "url": "https://gb.e-guide.renault.com/eng/Zoe-ph2" + } + ] + }, + { + "title": "All-New ZOE: Welcome to your new car", + "description": "", + "assetType": "VIDEO", + "assetRole": "CAR", + "renditions": [ + { + "url": "1OGwwmWHB6o" + } + ] + }, + { + "title": "Renault ZOE: All you need to know", + "description": "", + "assetType": "VIDEO", + "assetRole": "CAR", + "renditions": [ + { + "url": "_BVH-Rd6e5I" + } + ] + } + ], + "engineType": "5AQ", + "registrationCountry": { + "code": "FR" + }, + "radioType": { + "group": "425", + "code": "NA418", + "label": " FULL NAV DAB ETH - AUDI" + }, + "tcu": { + "group": "E70", + "code": "AIVCT", + "label": "AVEC BOITIER CONNECT AIVC" + }, + "brand": { + "label": "RENAULT" + }, + "deliveryDate": "2020-01-22", + "engineEnergyType": "ELEC", + "registrationDate": "2020-01-13", + "gearbox": { + "group": "427", + "code": "BVEL", + "label": "BOITE A VARIATEUR ELECTRIQUE" + }, + "model": { + "group": "971", + "code": "X102VE", + "label": "ZOE" + }, + "electrical": true, + "energy": { + "group": "019", + "code": "ELEC", + "label": "ELECTRIQUE" + }, + "navigationAssistanceLevel": { + "group": "408", + "code": "SAN408", + "label": "CRITERE DE CONTEXTE" + }, + "yearsOfMaintenance": 12, + "rlinkStore": false, + "radioCode": "1234", + "registrationNumber": "REG-NUMBER", + "modelSCR": "ZOE", + "easyConnectStore": false, + "engineRatio": "605", + "battery": { + "group": "968", + "code": "BT4AR1", + "label": "BATTERIE BT4AR1" + }, + "vin": "VF1AAAAA555777999", + "retrievedFromDhs": false, + "vcd": "ASCOD0/DLIGM2/SSTINC/KITPOU/SKTPGR/SSCCPC/SDPSEC/FDIU2/SSMAP/SSCALL/FACBA1/DANGMO/SSRCAR/SSCABD/AIVCT/AVGSI/ITPK4/VOLNCH/REACTI/AVOSP1/SWALBO/SSDWGE/1234Y/SSAEBS/PRAHL/RRCAM/STANDA/X10/B10/EA3/MD/ELEC/DG/TEMP/TR4X2/AFURGE/RV/ABS/CAREG/LAC/VSTLAR/CPETIR/RET03/PROJAB/RALU16/CEAVRH/ADAC/AIRBA2/SERIE/DRA/DRAP13/HARM02/3ATRPH/SGAV01/BARRAB/TELNJ/SFBANA/KM/DPRPN/AVREPL/SSDECA/ABLAV/ASRESP/ALEVA/SCACBA/SOP02C/STHPLG/SKTGRV/VLCUIR/RETRCR/TRSEV1/RETC/LVAVIP/LVAREL/SASURV/KTGREP/SGSCHA/FRA01/APL03/FSTPO/ALOUC5/CMAR3P/SAN408/NA418/BVEL/AUTAUG/SPREST/RDIF01/ISOFIX/EQPEUR/HRGM01/SDPCLV/CHASTD/TL01A/SPRODI/SAN613/AIRBDE/PSMREC/ELC1/SSPTLP/SANCML/SEXTIN/PE2019/PHAS2/SAN913/THABT2/SSTYAD/SSHYB/052KWH/BT4AR1/VEC018/X102VE/NBT022/5AQ", + "firstRegistrationDate": "2020-01-13", + "deliveryCountry": { + "code": "FR", + "label": "FRANCE" + }, + "connectivityTechnology": "RLINK1", + "family": { + "group": "007", + "code": "X10", + "label": "FAMILLE X10" + }, + "version": { + "code": "INT A MD 1L" + } + }, + "status": "ACTIVE", + "createdDate": "2020-08-21T16:48:00.243967Z", + "cancellationReason": {}, + "linkType": "OWNER", + "connectedDriver": { + "role": "MAIN_DRIVER", + "lastModifiedDate": "2020-08-22T09:41:53.477398Z", + "createdDate": "2020-08-22T09:41:53.477398Z" + }, + "vin": "VF1AAAAA555777999", + "lastModifiedDate": "2020-11-29T22:01:21.162572Z", + "brand": "RENAULT", + "startDate": "2020-08-21", + "ownershipStartDate": "2020-01-13", + "ownershipEndDate": "2020-08-21" + } + ], + "accountId": "account-id-1" +} diff --git a/tests/test_binary_sensor.py b/tests/test_binary_sensor.py new file mode 100644 index 0000000..7b91f07 --- /dev/null +++ b/tests/test_binary_sensor.py @@ -0,0 +1,60 @@ +"""Tests for Renault sensors.""" +from unittest.mock import PropertyMock, patch + +from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN +from homeassistant.setup import async_setup_component +import pytest +from pytest_homeassistant_custom_component.common import ( + mock_device_registry, + mock_registry, +) + +from tests.const import MOCK_VEHICLES + +from . import create_vehicle_proxy, setup_renault_integration + + +@pytest.mark.parametrize("vehicle_type", MOCK_VEHICLES.keys()) +async def test_sensors(hass, vehicle_type): + """Test for Renault sensors.""" + await async_setup_component(hass, "persistent_notification", {}) + entity_registry = mock_registry(hass) + device_registry = mock_device_registry(hass) + + vehicle_proxy = await create_vehicle_proxy(hass, vehicle_type) + + with patch( + "custom_components.renault.RenaultHub.vehicles", + new_callable=PropertyMock, + return_value={ + vehicle_proxy.details.vin: vehicle_proxy, + }, + ), patch("custom_components.renault.SUPPORTED_PLATFORMS", [BINARY_SENSOR_DOMAIN]): + await setup_renault_integration(hass) + await hass.async_block_till_done() + + mock_vehicle = MOCK_VEHICLES[vehicle_type] + expected_entities = mock_vehicle.get(BINARY_SENSOR_DOMAIN, []) + if len(expected_entities) > 0: + assert len(device_registry.devices) == 1 + expected_device = mock_vehicle["expected_device"] + registry_entry = device_registry.async_get_device( + expected_device["identifiers"] + ) + assert registry_entry is not None + assert registry_entry.identifiers == expected_device["identifiers"] + assert registry_entry.manufacturer == expected_device["manufacturer"] + assert registry_entry.name == expected_device["name"] + assert registry_entry.model == expected_device["model"] + assert registry_entry.sw_version == expected_device["sw_version"] + + assert len(entity_registry.entities) == len(expected_entities) + for expected_entity in expected_entities: + entity_id = expected_entity["entity_id"] + registry_entry = entity_registry.entities.get(entity_id) + assert registry_entry is not None + assert registry_entry.unique_id == expected_entity["unique_id"] + assert registry_entry.unit_of_measurement == expected_entity.get("unit") + assert registry_entry.device_class == expected_entity.get("class") + state = hass.states.get(entity_id) + assert state.state == expected_entity["result"] diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 86f534e..7978d52 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -1,4 +1,4 @@ -"""Test the Renault config flow.""" +"""Tests for Renault config flow.""" from unittest.mock import patch from homeassistant import config_entries, data_entry_flow diff --git a/tests/test_device_tracker.py b/tests/test_device_tracker.py new file mode 100644 index 0000000..dbcac3a --- /dev/null +++ b/tests/test_device_tracker.py @@ -0,0 +1,60 @@ +"""Tests for Renault sensors.""" +from unittest.mock import PropertyMock, patch + +from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN +from homeassistant.setup import async_setup_component +import pytest +from pytest_homeassistant_custom_component.common import ( + mock_device_registry, + mock_registry, +) + +from tests.const import MOCK_VEHICLES + +from . import create_vehicle_proxy, setup_renault_integration + + +@pytest.mark.parametrize("vehicle_type", MOCK_VEHICLES.keys()) +async def test_sensors(hass, vehicle_type): + """Test for Renault sensors.""" + await async_setup_component(hass, "persistent_notification", {}) + entity_registry = mock_registry(hass) + device_registry = mock_device_registry(hass) + + vehicle_proxy = await create_vehicle_proxy(hass, vehicle_type) + + with patch( + "custom_components.renault.RenaultHub.vehicles", + new_callable=PropertyMock, + return_value={ + vehicle_proxy.details.vin: vehicle_proxy, + }, + ), patch("custom_components.renault.SUPPORTED_PLATFORMS", [DEVICE_TRACKER_DOMAIN]): + await setup_renault_integration(hass) + await hass.async_block_till_done() + + mock_vehicle = MOCK_VEHICLES[vehicle_type] + expected_entities = mock_vehicle.get(DEVICE_TRACKER_DOMAIN, []) + if len(expected_entities) > 0: + assert len(device_registry.devices) == 1 + expected_device = mock_vehicle["expected_device"] + registry_entry = device_registry.async_get_device( + expected_device["identifiers"] + ) + assert registry_entry is not None + assert registry_entry.identifiers == expected_device["identifiers"] + assert registry_entry.manufacturer == expected_device["manufacturer"] + assert registry_entry.name == expected_device["name"] + assert registry_entry.model == expected_device["model"] + assert registry_entry.sw_version == expected_device["sw_version"] + + assert len(entity_registry.entities) == len(expected_entities) + for expected_entity in expected_entities: + entity_id = expected_entity["entity_id"] + registry_entry = entity_registry.entities.get(entity_id) + assert registry_entry is not None + assert registry_entry.unique_id == expected_entity["unique_id"] + assert registry_entry.unit_of_measurement == expected_entity.get("unit") + assert registry_entry.device_class == expected_entity.get("class") + state = hass.states.get(entity_id) + assert state.state == expected_entity["result"] diff --git a/tests/test_init.py b/tests/test_init.py index 60abdad..3919c70 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -1,4 +1,4 @@ -"""Test the Renault setup process.""" +"""Tests for Renault setup process.""" from unittest.mock import patch import aiohttp diff --git a/tests/test_sensor.py b/tests/test_sensor.py new file mode 100644 index 0000000..3460e4d --- /dev/null +++ b/tests/test_sensor.py @@ -0,0 +1,57 @@ +"""Tests for Renault sensors.""" +from unittest.mock import PropertyMock, patch + +from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN +from homeassistant.setup import async_setup_component +import pytest +from pytest_homeassistant_custom_component.common import ( + mock_device_registry, + mock_registry, +) + +from tests.const import MOCK_VEHICLES + +from . import create_vehicle_proxy, setup_renault_integration + + +@pytest.mark.parametrize("vehicle_type", MOCK_VEHICLES.keys()) +async def test_sensors(hass, vehicle_type): + """Test for Renault sensors.""" + await async_setup_component(hass, "persistent_notification", {}) + entity_registry = mock_registry(hass) + device_registry = mock_device_registry(hass) + + vehicle_proxy = await create_vehicle_proxy(hass, vehicle_type) + + with patch( + "custom_components.renault.RenaultHub.vehicles", + new_callable=PropertyMock, + return_value={ + vehicle_proxy.details.vin: vehicle_proxy, + }, + ), patch("custom_components.renault.SUPPORTED_PLATFORMS", [SENSOR_DOMAIN]): + await setup_renault_integration(hass) + await hass.async_block_till_done() + + mock_vehicle = MOCK_VEHICLES[vehicle_type] + assert len(device_registry.devices) == 1 + expected_device = mock_vehicle["expected_device"] + registry_entry = device_registry.async_get_device(expected_device["identifiers"]) + assert registry_entry is not None + assert registry_entry.identifiers == expected_device["identifiers"] + assert registry_entry.manufacturer == expected_device["manufacturer"] + assert registry_entry.name == expected_device["name"] + assert registry_entry.model == expected_device["model"] + assert registry_entry.sw_version == expected_device["sw_version"] + + expected_entities = mock_vehicle[SENSOR_DOMAIN] + assert len(entity_registry.entities) == len(expected_entities) + for expected_entity in expected_entities: + entity_id = expected_entity["entity_id"] + registry_entry = entity_registry.entities.get(entity_id) + assert registry_entry is not None + assert registry_entry.unique_id == expected_entity["unique_id"] + assert registry_entry.unit_of_measurement == expected_entity.get("unit") + assert registry_entry.device_class == expected_entity.get("class") + state = hass.states.get(entity_id) + assert state.state == expected_entity["result"]