Files
StarPilot/openpilot/starpilot/galaxy/tests/test_volt_radar_settings.py
T
firestar5683 80fbb4f6db Feature registration
Register vehicle controls, planner modes, UI actions and Galaxy services after their providers exist. Wire the shared runtime entrypoints and cover their combined behavior.

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
Co-authored-by: Daniel Koepping <elkoled@gmail.com>
Co-authored-by: Danny <dannyirwin31@yahoo.com>
Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com>
Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com>
Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com>
Co-authored-by: Kacper Rączy <gfw.kra@gmail.com>
Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu>
Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com>
Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com>
Co-authored-by: stef <19478336+stefpi@users.noreply.github.com>
Co-authored-by: whoisdomi <dcantu83@gmail.com>

Co-authored-by: Intelli <contact@intelli.software>
Co-authored-by: haraschax <6804392+haraschax@users.noreply.github.com>
Co-authored-by: prabhaavp <prabhaav@msu.edu>
2026-10-14 20:02:39 -05:00

110 lines
4.8 KiB
Python

from types import SimpleNamespace
from unittest.mock import Mock
from pathlib import Path
import pytest
from opendbc.car.gm.values import CAR
from openpilot.common.params import Params
from openpilot.starpilot.car.gm.radar_recovery import KEY
from openpilot.starpilot.car.gm.tests.test_radar_recovery import vehicle
from openpilot.starpilot.favorites.actions import FEATURE_KEYS
from openpilot.starpilot.galaxy.settings import AuthorityContext, SettingsChanged, SettingsGateway
from openpilot.starpilot.ui.feature_settings_owner import FeatureSettingsOwner
from openpilot.starpilot.ui.feature_settings_state import FeaturePage, row_change, row_default
@pytest.fixture
def setup(tmp_path):
params = Params(str(tmp_path))
current = SimpleNamespace(cp=vehicle(), raw=b'confirmed-volt', parked=True, saved=False)
context = Mock(sample=lambda: AuthorityContext(current.parked, current.cp, current.raw, editing_saved_vehicle=current.saved))
gateway = SettingsGateway(params, context, clock=lambda: 10)
return params, current, gateway
def recovery_row(page):
return next(row for row in page['rows'] if row['label'] == 'Radar Recovery Alert')
def test_shared_galaxy_projection_default_and_owner_routed_reset(setup):
params, current, gateway = setup
page = gateway.page('vehicle', 'session', b'generation')
row = recovery_row(page)
assert row['label'] == 'Radar Recovery Alert' and row['value'] == row['defaultValue'] == 'Off'
assert row['choices'] == ['Off', 'On'] and row['resetAvailable']
assert row['reason'] == 'Play a chime and show a brief message when a radar fault clears. You must re-engage manually.'
assert params.get(KEY) is None
index = page['rows'].index(row)
intent = gateway.preview(page['view'], index, 0, 'session', b'generation', value='On')
current.parked = False
assert gateway.confirm(intent['intent'], 'session', b'generation')
assert params.get_bool(KEY)
page = gateway.page('vehicle', 'session', b'generation')
index = page['rows'].index(recovery_row(page))
intent = gateway.preview(page['view'], index, 0, 'session', b'generation', reset_default=True)
assert gateway.confirm(intent['intent'], 'session', b'generation')
assert not params.get_bool(KEY)
@pytest.mark.parametrize('kind', ['unknown', 'bolt', 'other_gm', 'radarless', 'passive', 'saved_selection'])
def test_ineligible_information_hidden_in_shared_page_and_search_projection(setup, kind):
_, current, gateway = setup
if kind == 'unknown':
current.cp = None
elif kind == 'bolt':
current.cp = vehicle(CAR.CHEVROLET_BOLT_EUV)
elif kind == 'other_gm':
current.cp = vehicle(CAR.GMC_ACADIA)
elif kind == 'radarless':
current.cp.radarUnavailable = True
elif kind == 'passive':
current.cp.passive = True
else:
current.saved = True
assert all(row['label'] != 'Radar Recovery Alert' for row in gateway.page('vehicle', 'session', b'generation')['rows'])
def test_no_native_settings_or_favorite_registration(setup):
params, current, gateway = setup
owner = FeatureSettingsOwner(params, lambda group: True, vehicle_fingerprint=lambda: current.cp.carFingerprint,
vehicle_params=lambda: current.cp)
state = owner.snapshot(FeaturePage.VEHICLE, parked=True, system_long=True, lateral_context=True, metric=False)
assert all(row.key != KEY for row in state.rows)
assert all(KEY not in keys for keys in FEATURE_KEYS.values())
galaxy_row = next(row for row in gateway._state('vehicle', gateway.context.sample()).rows if row.key == KEY)
request = row_change(galaxy_row)
assert request is not None
assert not owner.apply(request)
@pytest.mark.parametrize('change', ['vehicle', 'vin', 'saved', 'session', 'preference'])
def test_pending_write_cannot_cross_changed_context(setup, change):
params, current, gateway = setup
page = gateway.page('vehicle', 'session', b'generation')
index = page['rows'].index(recovery_row(page))
intent = gateway.preview(page['view'], index, 0, 'session', b'generation', value='On')
if change == 'vehicle':
current.cp = vehicle(CAR.CHEVROLET_BOLT_EUV)
current.raw = b'bolt'
elif change == 'vin':
current.cp.carVin = 'different'
elif change == 'saved':
current.saved = True
elif change == 'preference':
Path(params.get_param_path(KEY)).write_bytes(b'0')
try:
assert not gateway.confirm(intent['intent'], 'session', b'generation', session_valid=lambda: change != 'session')
except SettingsChanged:
pass
assert not params.get_bool(KEY)
def test_invalid_saved_preference_not_repaired_by_raw_reset(setup):
params, _, gateway = setup
Path(params.get_param_path(KEY)).write_bytes(b'bad')
row = next(row for row in gateway._state('vehicle', gateway.context.sample()).rows if row.key == KEY)
assert not row.available
assert row_change(row) is None and row_default(row) is None
assert Path(params.get_param_path(KEY)).read_bytes() == b'bad'