Files
StarPilot/openpilot/starpilot/drive_state/tests/test_confirmation_profile.py
T
firestar5683 a82935f326 User interfaces and Android Auto
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services.

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: Prabhaav Pillai <prabhaav@msu.edu>
Co-authored-by: Shane Smiskol <shane@smiskol.com>
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: pharmacomaniac <blittle65@gmail.com>

Co-authored-by: prabhaavp <prabhaav@msu.edu>
2026-10-14 20:02:39 -05:00

61 lines
3.0 KiB
Python

from typing import Any
import ast
from pathlib import Path
from types import SimpleNamespace as NS
from unittest.mock import Mock, patch
import sys
import time
import types
import pytest
from openpilot.starpilot.drive_state.owner import Mode, Rejected
from openpilot.starpilot.drive_state.tests.test_transport import fixture as fixture
@pytest.mark.parametrize('profile', ['compact', 'large'])
def test_force_offroad_uses_profile_dialog_and_submits_once(fixture, profile):
source = Path(__file__).resolve().parents[2] / 'ui/runtime_app.py'
tree = ast.parse(source.read_text())
session = next(node for node in tree.body if isinstance(node, ast.ClassDef) and node.name == 'StarShellSession')
method = next(node for node in session.body if isinstance(node, ast.FunctionDef) and node.name == '_drive_change')
ui = NS(started=True, started_frame=10)
gui = NS(push_widget=Mock(), texture=Mock(return_value='native-icon'))
result = NS(CONFIRM=1, CANCEL=0)
modules = {}
for name in ('openpilot.system.ui.widgets', 'openpilot.system.ui.widgets.confirm_dialog', 'openpilot.selfdrive.ui.mici.widgets.dialog'):
modules[name] = types.ModuleType(name)
modules['openpilot.system.ui.widgets'].DialogResult = result
compact = Mock(side_effect=lambda title, icon, callback, red: NS(confirm=lambda: callback()))
large = Mock(side_effect=lambda title, button, callback: NS(confirm=lambda: callback(result.CONFIRM), cancel=lambda: callback(result.CANCEL)))
modules['openpilot.selfdrive.ui.mici.widgets.dialog'].BigConfirmationDialog = compact
modules['openpilot.system.ui.widgets.confirm_dialog'].ConfirmDialog = large
namespace: dict[str, Any] = {'ui_state': ui, 'gui_app': gui, 'Profile': NS(COMPACT='compact'),
'ShellMode': NS(SETTINGS='settings'), 'DriveStateRejected': Rejected, 'time': time}
exec(compile(ast.Module(body=[method], type_ignores=[]), str(source), 'exec'), namespace)
native = NS(drive_state=fixture.control, profile=profile, selected='system', _mode='settings')
native._drive_change = types.MethodType(namespace['_drive_change'], native)
revision = fixture.owner.snapshot().revision
fixture.physical.allowed.return_value = False
with patch.dict(sys.modules, modules):
native._drive_change('offroad', revision)
assert fixture.owner.snapshot().mode == Mode.AUTO
assert compact.call_count == (profile == 'compact')
assert large.call_count == (profile == 'large')
dialog = gui.push_widget.call_args.args[0]
if profile == 'large':
dialog.cancel()
assert fixture.owner.snapshot().mode == Mode.AUTO
ui.started_frame += 1
dialog.confirm()
assert fixture.owner.snapshot().mode == Mode.AUTO
native._drive_change('offroad', revision)
dialog = gui.push_widget.call_args.args[0]
writes = len(fixture.owner.params.writes)
dialog.confirm()
assert fixture.owner.snapshot().mode == Mode.OFFROAD
assert len(fixture.owner.params.writes) == writes + 1
dialog.confirm()
assert len(fixture.owner.params.writes) == writes + 1