Skip to content

Commit

Permalink
Update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rikroe committed Jan 21, 2024
1 parent 119eadc commit ed2ffd2
Show file tree
Hide file tree
Showing 34 changed files with 480 additions and 458 deletions.
20 changes: 14 additions & 6 deletions bimmer_connected/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import json
from pathlib import Path
from typing import Any, Dict, List, Union
from typing import Any, Dict, Union

from bimmer_connected.api.regions import Regions
from bimmer_connected.const import CarBrands
Expand All @@ -23,7 +23,8 @@
VIN_I01_REX = "WBY00000000REXI01"
VIN_I20 = "WBA00000000DEMO01"

ALL_VEHICLES: Dict[str, List[Dict]] = {brand.value: [] for brand in CarBrands}
ALL_VEHICLES: Dict[str, Dict] = {brand.value: {} for brand in CarBrands}
ALL_PROFILES: Dict[str, Dict] = {}
ALL_STATES: Dict[str, Dict] = {}
ALL_CHARGING_SETTINGS: Dict[str, Dict] = {}

Expand All @@ -37,7 +38,7 @@

def get_fingerprint_state_count() -> int:
"""Return number of loaded vehicles."""
return sum([len(vehicles) for vehicles in ALL_VEHICLES.values()])
return len(ALL_STATES)


def get_fingerprint_charging_settings_count() -> int:
Expand All @@ -53,10 +54,17 @@ def load_response(path: Union[Path, str]) -> Any:
return file.read().decode("UTF-8")


for fingerprint in RESPONSE_DIR.rglob("*-eadrax-vcs_v4_vehicles.json"):
for fingerprint in RESPONSE_DIR.rglob("*-eadrax-vcs_v5_vehicle-list.json"):
brand = fingerprint.stem.split("-")[0]
for vehicle in load_response(fingerprint):
ALL_VEHICLES[brand].append(vehicle)
response = load_response(fingerprint)

if ALL_VEHICLES[brand].get("mappingInfos"):
ALL_VEHICLES[brand]["mappingInfos"].extend(response["mappingInfos"])
else:
ALL_VEHICLES[brand] = response

for profile in RESPONSE_DIR.rglob("*-eadrax-vcs_v5_vehicle-data_profile_*.json"):
ALL_PROFILES[profile.stem.split("_")[-1]] = load_response(profile)

for state in RESPONSE_DIR.rglob("*-eadrax-vcs_v4_vehicles_state_*.json"):
ALL_STATES[state.stem.split("_")[-1]] = load_response(state)
Expand Down
23 changes: 19 additions & 4 deletions bimmer_connected/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ class MyBMWMockRouter(respx.MockRouter):
def __init__(
self,
vehicles_to_load: Optional[List[str]] = None,
profiles: Optional[Dict[str, Dict]] = None,
states: Optional[Dict[str, Dict]] = None,
charging_settings: Optional[Dict[str, Dict]] = None,
) -> None:
"""Initialize the MyBMWMockRouter with clean responses."""
super().__init__(assert_all_called=False)
self.vehicles_to_load = vehicles_to_load or []
self.profiles = deepcopy(profiles) if profiles else {}
self.states = deepcopy(states) if states else {}
self.charging_settings = deepcopy(charging_settings) if charging_settings else {}

Expand Down Expand Up @@ -110,7 +112,8 @@ def add_login_routes(self) -> None:
def add_vehicle_routes(self) -> None:
"""Add routes for vehicle requests."""

self.get("/eadrax-vcs/v4/vehicles").mock(side_effect=self.vehicles_sideeffect)
self.post("/eadrax-vcs/v5/vehicle-list").mock(side_effect=self.vehicles_sideeffect)
self.get("/eadrax-vcs/v5/vehicle-data/profile").mock(side_effect=self.vehicle_profile_sideeffect)
self.get("/eadrax-vcs/v4/vehicles/state", name="state").mock(side_effect=self.vehicle_state_sideeffect)
self.get("/eadrax-crccs/v2/vehicles").mock(side_effect=self.vehicle_charging_settings_sideeffect)

Expand Down Expand Up @@ -171,15 +174,27 @@ def vehicles_sideeffect(self, request: httpx.Request) -> httpx.Response:
# Test if given region is valid
_ = Regions(x_user_agent[3])

fingerprints = ALL_VEHICLES.get(brand, [])
fingerprints = deepcopy(ALL_VEHICLES.get(brand, {"mappingInfos": []}))
if self.vehicles_to_load:
fingerprints = [f for f in fingerprints if f["vin"] in self.vehicles_to_load]
fingerprints["mappingInfos"] = [
f for f in fingerprints["mappingInfos"] if f["vin"] in self.vehicles_to_load
]

# Ensure order
fingerprints = sorted(fingerprints, key=lambda v: v["vin"])
fingerprints["mappingInfos"] = sorted(fingerprints["mappingInfos"], key=lambda v: v["vin"])

return httpx.Response(200, json=fingerprints)

def vehicle_profile_sideeffect(self, request: httpx.Request) -> httpx.Response:
"""Return /vehicle-data/profile response based on vin."""
x_user_agent = request.headers.get("x-user-agent", "").split(";")
assert len(x_user_agent) == 4

try:
return httpx.Response(200, json=self.profiles[request.headers["bmw-vin"]])
except KeyError:
return httpx.Response(404)

def vehicle_state_sideeffect(self, request: httpx.Request) -> httpx.Response:
"""Return /vehicles response based on x-user-agent."""
x_user_agent = request.headers.get("x-user-agent", "").split(";")
Expand Down
2 changes: 2 additions & 0 deletions bimmer_connected/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from . import (
ALL_CHARGING_SETTINGS,
ALL_PROFILES,
ALL_STATES,
TEST_PASSWORD,
TEST_REGION,
Expand All @@ -25,6 +26,7 @@ def bmw_fixture(request: pytest.FixtureRequest) -> Generator[respx.MockRouter, N
# Now we can start patching the API calls
router = MyBMWMockRouter(
vehicles_to_load=getattr(request, "param", []),
profiles=ALL_PROFILES,
states=ALL_STATES,
charging_settings=ALL_CHARGING_SETTINGS,
)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
{
"capabilities": {
"a4aType": "USB_ONLY",
"checkSustainabilityDPP": false,
"alarmSystem": false,
"climateFunction": "VENTILATION",
"climateNow": true,
"climateTimerTrigger": "START_TIMER",
"digitalKey": {
"bookedServicePackage": "NONE",
"state": "NOT_AVAILABLE"
"isDigitalKeyFirstSupported": false,
"state": "NOT_AVAILABLE",
"vehicleSoftwareUpgradeRequired": false
},
"horn": true,
"isBmwChargingSupported": false,
Expand All @@ -27,9 +29,12 @@
"isDataPrivacyEnabled": false,
"isEasyChargeEnabled": false,
"isEvGoChargingSupported": false,
"isLocationBasedChargingSettingsSupported": false,
"isMiniChargingSupported": false,
"isNonLscFeatureEnabled": true,
"isOptimizedChargingSupported": false,
"isPersonalPictureUploadSupported": false,
"isPlugAndChargeSupported": false,
"isRemoteEngineStartSupported": false,
"isRemoteHistoryDeletionSupported": false,
"isRemoteHistorySupported": true,
Expand All @@ -46,7 +51,7 @@
"sendPoi": true,
"specialThemeSupport": [],
"unlock": true,
"vehicleFinder": true,
"vehicleFinder": false,
"vehicleStateSource": "A4A"
},
"state": {
Expand All @@ -59,76 +64,44 @@
"climateTimers": [
{
"departureTime": {
"hour": 6,
"minute": 40
"hour": 7,
"minute": 0
},
"isWeeklyTimer": true,
"timerAction": "ACTIVATE",
"timerWeekDays": [
"THURSDAY",
"SUNDAY"
]
"isWeeklyTimer": false,
"timerAction": "DEACTIVATE",
"timerWeekDays": []
},
{
"departureTime": {
"hour": 12,
"minute": 50
"hour": 7,
"minute": 0
},
"isWeeklyTimer": false,
"timerAction": "ACTIVATE",
"isWeeklyTimer": true,
"timerAction": "DEACTIVATE",
"timerWeekDays": [
"MONDAY"
]
},
{
"departureTime": {
"hour": 18,
"minute": 59
"hour": 7,
"minute": 0
},
"isWeeklyTimer": true,
"timerAction": "DEACTIVATE",
"timerWeekDays": [
"WEDNESDAY"
"MONDAY"
]
}
],
"combustionFuelLevel": {
"remainingFuelLiters": 14
},
"driverPreferences": {
"lscPrivacyMode": "OFF"
},
"isLeftSteering": true,
"isLscSupported": false,
"lastFetched": "2022-06-01T19:18:54.528Z",
"lastUpdatedAt": "2021-11-01T16:02:44Z",
"requiredServices": [
{
"dateTime": "2021-11-01T00:00:00.000Z",
"description": "Wechsel demnächst fällig. Bitte Termin mit Ihrem Servicepartner vereinbaren.",
"status": "PENDING",
"type": "BRAKE_FLUID"
},
{
"dateTime": "2022-07-01T00:00:00.000Z",
"description": "Nächster Service nach der angegebenen Fahrstrecke oder zum angegebenen Termin.",
"mileage": 9000,
"status": "OK",
"type": "OIL"
},
{
"dateTime": "2022-07-01T00:00:00.000Z",
"description": "Nächste Sichtprüfung nach der angegebenen Fahrstrecke oder zum angegebenen Termin.",
"mileage": 9000,
"status": "OK",
"type": "VEHICLE_CHECK"
},
{
"dateTime": "2023-02-01T00:00:00.000Z",
"description": "Nächste gesetzliche Fahrzeuguntersuchung zum angegebenen Termin.",
"status": "OK",
"type": "VEHICLE_TUV"
}
]
"lastFetched": "2024-01-20T10:18:57.283Z",
"lastUpdatedAt": "0001-01-01T00:00:00Z",
"requiredServices": [],
"securityOverviewMode": null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"bodyType": "F31",
"brand": "BMW",
"color": 4281545523,
"countryOfOrigin": "DE",
"driveTrain": "COMBUSTION",
"driverGuideInfo": {
"androidAppScheme": "com.bmwgroup.driversguide.row",
"androidStoreUrl": "https://play.google.com/store/apps/details?id=com.bmwgroup.driversguide.row",
"iosAppScheme": "bmwdriversguide:///open",
"iosStoreUrl": "https://apps.apple.com/de/app/id714042749?mt=8"
},
"headUnitRaw": "NBT",
"headUnitType": "NBT",
"hmiVersion": "ID4",
"model": "320d xDrive",
"softwareVersionCurrent": {
"iStep": 502,
"puStep": {
"month": 11,
"year": 13
},
"seriesCluster": "F020"
},
"softwareVersionExFactory": {
"iStep": 502,
"puStep": {
"month": 11,
"year": 13
},
"seriesCluster": "F020"
},
"vin": "WBA00000000000F31",
"year": 2013
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"gcid": "ceb64158-d2ca-47e9-9ee6-cbffb881434e",
"mappingInfos": [
{
"isAssociated": false,
"isLmmEnabled": false,
"isPrimaryUser": true,
"mappingStatus": "CONFIRMED",
"vehicleMappingType": "CONNECTED",
"vin": "WBA00000000000F31"
}
]
}

This file was deleted.

Loading

0 comments on commit ed2ffd2

Please sign in to comment.