mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-21 00:03:45 +08:00
170 lines
5.1 KiB
Python
170 lines
5.1 KiB
Python
import hashlib
|
|
import json
|
|
|
|
from openpilot.selfdrive.ui.layouts.settings.starpilot.navigation import (
|
|
MapboxSearchClient,
|
|
_NavigationParams,
|
|
_add_favorite_destination,
|
|
_favorite_destination_id,
|
|
_favorite_payload_for_galaxy,
|
|
_load_favorite_destinations,
|
|
_remove_favorite_destination,
|
|
_update_favorite_destination,
|
|
)
|
|
|
|
|
|
def test_favorites_get_stable_ids_and_deduplicate_by_id():
|
|
favorite = {
|
|
"name": "Home",
|
|
"latitude": "41.881832",
|
|
"longitude": "-87.623177",
|
|
"routeId": "main",
|
|
}
|
|
expected_id = _favorite_destination_id(favorite)
|
|
|
|
added = _add_favorite_destination("[]", favorite)
|
|
duplicate = _add_favorite_destination(json.dumps(added), {**favorite, "id": expected_id})
|
|
|
|
assert added == [{**favorite, "latitude": 41.881832, "longitude": -87.623177, "id": expected_id}]
|
|
assert duplicate == added
|
|
assert _load_favorite_destinations(json.dumps(added)) == added
|
|
|
|
|
|
def test_favorite_id_preserves_galaxy_hash_input_for_numeric_coordinates():
|
|
favorite = {"name": "One", "latitude": 1.0, "longitude": 2.0}
|
|
expected = hashlib.sha1(b"2.0,1.0||One").hexdigest()
|
|
|
|
assert _favorite_destination_id(favorite) == expected
|
|
|
|
|
|
def test_new_favorites_use_galaxys_default_route_id_contract():
|
|
destination = {"name": "Home", "latitude": 1.0, "longitude": 2.0}
|
|
|
|
assert _favorite_payload_for_galaxy(destination)["routeId"] == "main"
|
|
assert _favorite_payload_for_galaxy({**destination, "routeId": "alternate"})["routeId"] == "alternate"
|
|
|
|
|
|
def test_favorite_special_locations_are_mutually_exclusive():
|
|
raw = json.dumps([
|
|
{"id": "home", "name": "Home", "latitude": 1, "longitude": 2, "is_home": True},
|
|
{"id": "work", "name": "Work", "latitude": 3, "longitude": 4},
|
|
])
|
|
|
|
updated = _update_favorite_destination(raw, {"id": "work"}, is_work=True)
|
|
|
|
assert updated is not None
|
|
assert updated[0].get("is_home") is True
|
|
assert updated[1].get("is_work") is True
|
|
assert updated[1].get("is_home") is None
|
|
|
|
|
|
def test_favorite_rename_can_target_legacy_route_id_without_coordinates():
|
|
raw = json.dumps([{
|
|
"name": "Old name",
|
|
"routeId": "route-1",
|
|
"latitude": 1,
|
|
"longitude": 2,
|
|
}])
|
|
|
|
updated = _update_favorite_destination(raw, {"routeId": "route-1"}, name="New name")
|
|
|
|
assert updated is not None
|
|
assert updated[0]["name"] == "New name"
|
|
|
|
|
|
def test_favorite_can_be_removed_by_legacy_payload_identity():
|
|
raw = json.dumps([
|
|
{"name": "Keep", "latitude": 1, "longitude": 2},
|
|
{"name": "Remove", "latitude": 3, "longitude": 4},
|
|
])
|
|
|
|
updated = _remove_favorite_destination(raw, {"name": "Remove", "latitude": 3, "longitude": 4})
|
|
|
|
assert [favorite["name"] for favorite in updated] == ["Keep"]
|
|
|
|
|
|
def test_navigation_params_commits_destination_and_clears_runtime_state():
|
|
class FakeParams:
|
|
def __init__(self):
|
|
self.values = {}
|
|
self.removed = []
|
|
|
|
def get(self, key, encoding=None, default=None):
|
|
value = self.values.get(key, default)
|
|
if encoding == "utf-8" and isinstance(value, bytes):
|
|
return value.decode("utf-8")
|
|
return value
|
|
|
|
def put(self, key, value):
|
|
self.values[key] = value
|
|
|
|
def remove(self, key):
|
|
self.removed.append(key)
|
|
self.values.pop(key, None)
|
|
|
|
params = FakeParams()
|
|
memory = FakeParams()
|
|
navigation = _NavigationParams(params, memory)
|
|
|
|
destination = navigation.set_destination({"name": "Home", "latitude": 1, "longitude": 2})
|
|
assert navigation.clear_navigation() is True
|
|
|
|
assert destination["place_name"] == "Home"
|
|
assert params.values["ApiCache_NavDestinations"][0]["place_name"] == "Home"
|
|
assert "NavDestination" in params.removed
|
|
assert memory.removed == ["NavInstructionState", "NavInstructionCollapsed"]
|
|
|
|
|
|
class FakeResponse:
|
|
def __init__(self, payload, status_code=200):
|
|
self._payload = payload
|
|
self.status_code = status_code
|
|
|
|
def raise_for_status(self):
|
|
if self.status_code >= 400:
|
|
raise RuntimeError(f"HTTP {self.status_code}")
|
|
|
|
def json(self):
|
|
return self._payload
|
|
|
|
|
|
class FakeSession:
|
|
def __init__(self):
|
|
self.calls = []
|
|
|
|
def get(self, url, *, params, timeout):
|
|
self.calls.append((url, params, timeout))
|
|
if url.endswith("/suggest"):
|
|
return FakeResponse({
|
|
"suggestions": [{
|
|
"name": "OpenAI",
|
|
"full_address": "OpenAI, San Francisco, CA",
|
|
"mapbox_id": "place.openai",
|
|
}],
|
|
})
|
|
return FakeResponse({
|
|
"features": [{
|
|
"properties": {"name": "OpenAI", "full_address": "OpenAI, San Francisco, CA"},
|
|
"geometry": {"coordinates": [-122.401, 37.789]},
|
|
}],
|
|
})
|
|
|
|
|
|
def test_mapbox_search_and_retrieve_use_public_token_only():
|
|
session = FakeSession()
|
|
client = MapboxSearchClient(session=session)
|
|
|
|
results = client.search("openai", "public-token", "session-token", proximity=(-122.4, 37.8), language="en")
|
|
resolved = client.resolve(results[0], "public-token", "session-token")
|
|
|
|
assert results[0].name == "OpenAI"
|
|
assert results[0].latitude is None
|
|
assert resolved.to_destination() == {
|
|
"name": "OpenAI",
|
|
"place_name": "OpenAI",
|
|
"latitude": 37.789,
|
|
"longitude": -122.401,
|
|
}
|
|
assert session.calls[0][1]["access_token"] == "public-token"
|
|
assert "secret" not in session.calls[0][1]
|