231 lines
8.6 KiB
Python
231 lines
8.6 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from cognitive_agent.application.conversation_state import ConversationStateStore
|
|
|
|
|
|
class NativeStateSyncTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.store = ConversationStateStore()
|
|
|
|
def apply(self, action: dict) -> dict:
|
|
return self.store.apply_successful_actions(
|
|
"conv-native-sync",
|
|
"test",
|
|
[{**action, "feedback_source": "physical_can_ch1"}],
|
|
[],
|
|
)
|
|
|
|
def test_driver_seat_native_feedback_never_updates_passenger(self) -> None:
|
|
state = self.apply(
|
|
{
|
|
"domain": "seat",
|
|
"capability": "seat.set_driver_heating_native",
|
|
"target": "driver",
|
|
"parameters": {"state": "low"},
|
|
}
|
|
)
|
|
self.assertEqual(state["devices"]["driver"]["heating"]["state"], "on")
|
|
self.assertEqual(state["devices"]["driver"]["heating"]["level"], 1)
|
|
self.assertEqual(
|
|
state["devices"]["driver"]["heating"]["feedback_source"],
|
|
"physical_can_ch1",
|
|
)
|
|
self.assertEqual(state["devices"]["passenger"]["heating"]["state"], "off")
|
|
|
|
def test_window_feedback_updates_frontend_domain_state(self) -> None:
|
|
state = self.apply(
|
|
{
|
|
"domain": "window",
|
|
"capability": "window.set_position",
|
|
"target": "front_left",
|
|
"parameters": {"position_pct": 25},
|
|
}
|
|
)
|
|
window = state["domain_devices"]["window"]["positions"]["front_left"]
|
|
self.assertEqual(window["position_pct"], 25)
|
|
self.assertFalse(window["closed"])
|
|
self.assertEqual(window["feedback_source"], "physical_can_ch1")
|
|
|
|
def test_rear_lock_updates_only_rear_locks(self) -> None:
|
|
state = self.apply(
|
|
{
|
|
"domain": "door",
|
|
"capability": "door.set_rear_lock",
|
|
"target": "rear",
|
|
"parameters": {"state": "lock"},
|
|
}
|
|
)
|
|
locks = state["domain_devices"]["door"]["locks"]
|
|
self.assertEqual(locks["rear_left"]["state"], "lock")
|
|
self.assertEqual(locks["rear_right"]["state"], "lock")
|
|
self.assertEqual(locks["front_left"]["state"], "unknown")
|
|
|
|
def test_vehicle_lock_projection_updates_logical_and_all_door_states(self) -> None:
|
|
state = self.apply(
|
|
{
|
|
"domain": "door",
|
|
"capability": "door.set_vehicle_lock",
|
|
"target": "vehicle",
|
|
"parameters": {"state": "lock"},
|
|
}
|
|
)
|
|
door = state["domain_devices"]["door"]
|
|
self.assertEqual(door["vehicle_lock"]["state"], "lock")
|
|
self.assertTrue(
|
|
all(item["state"] == "lock" for item in door["locks"].values())
|
|
)
|
|
|
|
def test_authoritative_ch1_feedback_overrides_requested_ui_projection(self) -> None:
|
|
state = self.store.synchronize_physical_ch1_feedback(
|
|
"conv-native-sync",
|
|
[
|
|
{
|
|
"source": "physical_can_ch1",
|
|
"channel": 1,
|
|
"frame_id": "0x404",
|
|
"feedback_frame_id": "0x404",
|
|
"valid": True,
|
|
"verification": {
|
|
"authoritative": True,
|
|
"channel": 1,
|
|
"simulated": False,
|
|
"feedback_required": True,
|
|
"feedback_observed": True,
|
|
"feedback_match": True,
|
|
"frame_id": "0x404",
|
|
"payload_size": 8,
|
|
},
|
|
"actuator_state": {
|
|
"driver": {
|
|
"ventilation": {"state": "on", "level": 3},
|
|
"massage": {"mode": "relax", "strength": "weak"},
|
|
}
|
|
},
|
|
"domain_state": {
|
|
"climate": {
|
|
"power": "on",
|
|
"ac": "on",
|
|
"control_mode": "manual",
|
|
"cycle_mode": "internal",
|
|
"fan_level": 3,
|
|
"zones": {
|
|
"driver": {
|
|
"temperature_c": 24,
|
|
"outlet_mode": "defrost",
|
|
}
|
|
},
|
|
},
|
|
"roof": {
|
|
"shade_position_pct": 2,
|
|
"motion_state": "stopped",
|
|
},
|
|
"ambient_light": {
|
|
"power": "on",
|
|
"front_brightness_level": 3,
|
|
"rear_brightness_level": 3,
|
|
"front_color_index": 32,
|
|
"rear_color_index": 32,
|
|
},
|
|
"door": {
|
|
"locks": {
|
|
"rear_left": {"state": "lock"},
|
|
"rear_right": {"state": "lock"},
|
|
}
|
|
},
|
|
"window": {
|
|
"positions": {
|
|
"front_left": {
|
|
"position_pct": 9,
|
|
"closed": False,
|
|
}
|
|
}
|
|
},
|
|
},
|
|
}
|
|
],
|
|
)
|
|
|
|
self.assertEqual(state["devices"]["driver"]["ventilation"]["level"], 3)
|
|
self.assertEqual(
|
|
state["devices"]["driver"]["ventilation"]["feedback_source"],
|
|
"physical_can_ch1",
|
|
)
|
|
climate = state["domain_devices"]["climate"]
|
|
self.assertEqual(climate["zones"]["driver"]["outlet_mode"], "defrost")
|
|
self.assertEqual(climate["cycle_mode"], "internal")
|
|
self.assertEqual(climate["feedback_source"], "physical_can_ch1")
|
|
self.assertEqual(state["domain_devices"]["roof"]["shade_position_pct"], 2)
|
|
self.assertEqual(state["domain_devices"]["ambient_light"]["brightness_pct"], 100)
|
|
self.assertEqual(
|
|
state["domain_devices"]["door"]["locks"]["rear_left"]["feedback_source"],
|
|
"physical_can_ch1",
|
|
)
|
|
self.assertEqual(
|
|
state["domain_devices"]["window"]["positions"]["front_left"]["position_pct"],
|
|
9,
|
|
)
|
|
self.assertNotIn(
|
|
"feedback_source",
|
|
state["domain_devices"]["window"]["positions"]["rear_left"],
|
|
)
|
|
self.assertNotIn(
|
|
"feedback_source",
|
|
state["domain_devices"]["door"]["locks"]["front_left"],
|
|
)
|
|
|
|
def test_non_authoritative_feedback_is_ignored(self) -> None:
|
|
before = self.store.snapshot("conv-native-sync")
|
|
after = self.store.synchronize_physical_ch1_feedback(
|
|
"conv-native-sync",
|
|
[
|
|
{
|
|
"source": "physical_can_ch0",
|
|
"channel": 0,
|
|
"valid": True,
|
|
"domain_state": {"climate": {"power": "on"}},
|
|
}
|
|
],
|
|
)
|
|
self.assertEqual(after, before)
|
|
|
|
def test_unverified_or_empty_feedback_never_updates_state(self) -> None:
|
|
before = self.store.snapshot("conv-native-sync")
|
|
for feedback in (
|
|
{
|
|
"source": "physical_can_ch1",
|
|
"channel": 1,
|
|
"frame_id": "0x404",
|
|
"feedback_frame_id": "0x404",
|
|
"valid": True,
|
|
"domain_state": {"climate": {"power": "on"}},
|
|
},
|
|
{
|
|
"source": "physical_can_ch1",
|
|
"channel": 1,
|
|
"frame_id": "0x404",
|
|
"feedback_frame_id": "0x404",
|
|
"valid": True,
|
|
"verification": {
|
|
"authoritative": True,
|
|
"channel": 1,
|
|
"simulated": False,
|
|
"feedback_required": True,
|
|
"feedback_observed": True,
|
|
"feedback_match": True,
|
|
"frame_id": "0x404",
|
|
"payload_size": 8,
|
|
},
|
|
},
|
|
):
|
|
with self.subTest(feedback=feedback):
|
|
after = self.store.synchronize_physical_ch1_feedback(
|
|
"conv-native-sync", [feedback]
|
|
)
|
|
self.assertEqual(after, before)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|