from __future__ import annotations import tempfile import unittest from pathlib import Path import yaml from cognitive_agent.application.mode_profile import ModeProfileRegistry from cognitive_agent.application.seat_service import REPOSITORY_ROOT class ModeProfileRegistryTests(unittest.TestCase): def test_zero_gravity_profile_matches_alias_and_builds_requests(self) -> None: registry = ModeProfileRegistry(REPOSITORY_ROOT / "config" / "modes") matched = registry.match_text("副驾驶进入零重力模式", vehicle_id="denza_n7") self.assertEqual([profile.id for profile in matched], ["zero_gravity"]) self.assertEqual(matched[0].vehicle_ids, ("denza_n7",)) requests = registry.requests_for_profiles(matched) self.assertGreaterEqual(len(requests), 4) self.assertEqual(requests[0]["domain"], "seat") self.assertEqual(requests[0]["capability"], "seat.set_longitudinal_position") self.assertEqual(requests[0]["target_scope"], "passenger") self.assertIn( {"name": "position_pct", "value": 100}, requests[0]["parameters"], ) by_capability = {request["capability"]: request for request in requests} self.assertEqual( by_capability["seat.set_cushion_tilt"]["parameters"], [{"name": "position_pct", "value": 100}], ) self.assertEqual( by_capability["seat.set_backrest_recline"]["parameters"], [ {"name": "position_pct", "value": 81}, {"name": "angle_deg", "value": 150}, ], ) self.assertEqual( by_capability["seat.set_legrest_height"]["parameters"], [ {"name": "position_pct", "value": 87}, {"name": "angle_deg", "value": 163}, ], ) public = registry.public_modes() self.assertIn("零重力模式", {item["name"] for item in public}) self.assertNotIn( "zero_gravity", {profile.id for profile in registry.match_text("副驾驶进入零重力模式", vehicle_id="other_vehicle")}, ) def test_reference_modes_are_denza_specific(self) -> None: registry = ModeProfileRegistry(REPOSITORY_ROOT / "config" / "modes") expected_ids = { "zero_gravity", "cruise_sofa", "leisure_lounger", "nap", "easy_entry_exit", "baby_nap", "office", "meditation_space", "electric_beach_chair", "queen_passenger_driving", "calf_decompression_float", } denza_modes = registry.public_modes(vehicle_id="denza_n7") denza_ids = {mode["id"] for mode in denza_modes} self.assertTrue(expected_ids.issubset(denza_ids)) self.assertTrue( expected_ids.isdisjoint( {mode["id"] for mode in registry.public_modes(vehicle_id="other_vehicle")} ) ) self.assertEqual( registry.match_text("进入办公模式", vehicle_id="denza_n7")[0].id, "office", ) self.assertEqual( registry.match_text("进入小腿解压悬浮模式", vehicle_id="denza_n7")[0].id, "calf_decompression_float", ) def test_denza_mode_positions_use_corrected_n7_zero_points(self) -> None: registry = ModeProfileRegistry(REPOSITORY_ROOT / "config" / "modes") expected_positions = { "baby_nap": (81, 30), "calf_decompression_float": (51, 75), "cruise_sofa": (51, 30), "easy_entry_exit": (100, 0), "electric_beach_chair": (100, 0), "leisure_lounger": (51, 30), "meditation_space": (100, 44), "nap": (0, 0), "office": (72, 22), "queen_passenger_driving": (72, 38), "zero_gravity": (100, 100), } profiles = { profile.id: profile for profile in registry.profiles() if profile.id in expected_positions and profile.vehicle_ids == ("denza_n7",) } actual_positions = {} for profile_id, profile in profiles.items(): requests = { request["capability"]: request for request in registry.requests_for_profiles([profile]) } actual_positions[profile_id] = tuple( next( parameter["value"] for parameter in requests[capability]["parameters"] if parameter["name"] == "position_pct" ) for capability in ( "seat.set_longitudinal_position", "seat.set_cushion_tilt", ) ) self.assertEqual(actual_positions, expected_positions) def test_common_modes_are_visible_with_vehicle_specific_overrides(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) common = root / "common" denza = root / "vehicles" / "denza_n7" other = root / "vehicles" / "other_vehicle" common.mkdir(parents=True) denza.mkdir(parents=True) other.mkdir(parents=True) (common / "relax.yaml").write_text( """ id: relax name: 放松模式 aliases: - relax description: 公共放松模式。 operations: - domain: roof capability: roof.set_transmittance target_scope: vehicle operation: set parameters: transmittance_pct: 45 """.strip() + "\n", encoding="utf-8", ) (denza / "relax.yaml").write_text( """ id: relax name: N7 放松模式 aliases: - relax description: N7 专属放松模式。 scope: vehicle_ids: - denza_n7 operations: - domain: roof capability: roof.set_transmittance target_scope: vehicle operation: set parameters: transmittance_pct: 20 """.strip() + "\n", encoding="utf-8", ) (other / "nap.yaml").write_text( """ id: nap name: 午休模式 description: 其他车型专属午休模式。 operations: - domain: roof capability: roof.set_transmittance target_scope: vehicle operation: set parameters: transmittance_pct: 10 """.strip() + "\n", encoding="utf-8", ) registry = ModeProfileRegistry(root) denza_matches = registry.match_text("进入放松模式", vehicle_id="denza_n7") other_matches = registry.match_text("进入放松模式", vehicle_id="other_vehicle") self.assertEqual([profile.name for profile in denza_matches], ["N7 放松模式"]) self.assertEqual([profile.name for profile in other_matches], ["放松模式"]) self.assertEqual( {profile.id for profile in registry.match_text("进入午休模式", vehicle_id="denza_n7")}, set(), ) self.assertEqual( {mode["id"] for mode in registry.public_modes(vehicle_id="denza_n7")}, {"relax"}, ) def test_save_mode_profile_persists_yaml_and_reloads(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) registry = ModeProfileRegistry(root) profile = registry.save_mode( "露营模式", [ { "domain": "roof", "capability": "roof.set_transmittance", "target_scope": "vehicle", "operation": "set", "parameters": {"transmittance_pct": 20}, "reason": "保存最近一次天幕目标。", } ], vehicle_id="denza_n7", ) saved_path = Path(profile.source) self.assertTrue(saved_path.is_file()) self.assertEqual( saved_path.relative_to(root).parts[:3], ("vehicles", "denza_n7", "user"), ) document = yaml.safe_load(saved_path.read_text(encoding="utf-8")) self.assertEqual(document["name"], "露营模式") self.assertEqual(document["scope"]["vehicle_ids"], ["denza_n7"]) self.assertEqual(document["operations"][0]["domain"], "roof") reloaded = ModeProfileRegistry(root) matched = reloaded.match_text("进入露营模式", vehicle_id="denza_n7") self.assertEqual([item.name for item in matched], ["露营模式"]) self.assertEqual( reloaded.match_text("进入露营模式", vehicle_id="other_vehicle"), [], ) requests = reloaded.requests_for_profiles(matched) self.assertEqual(requests[0]["capability"], "roof.set_transmittance") self.assertEqual( requests[0]["parameters"], [{"name": "transmittance_pct", "value": 20}], ) def test_update_mode_profile_backs_up_initial_yaml_and_restores(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) registry = ModeProfileRegistry(root) profile = registry.save_mode( "露营模式", [ { "domain": "roof", "capability": "roof.set_transmittance", "target_scope": "vehicle", "operation": "set", "parameters": {"transmittance_pct": 20}, "reason": "原始天幕目标。", } ], vehicle_id="denza_n7", ) updated = registry.update_mode( profile, [ { "domain": "roof", "capability": "roof.set_transmittance", "target_scope": "vehicle", "operation": "set", "parameters": {"transmittance_pct": 50}, "reason": "用户修改天幕目标。", } ], ) self.assertTrue(Path(profile.source).with_suffix(".yaml.initial.bak").is_file()) requests = registry.requests_for_profiles([updated]) self.assertEqual( requests[0]["parameters"], [{"name": "transmittance_pct", "value": 50}], ) restored = registry.restore_initial_mode(updated) restored_requests = registry.requests_for_profiles([restored]) self.assertEqual( restored_requests[0]["parameters"], [{"name": "transmittance_pct", "value": 20}], ) if __name__ == "__main__": unittest.main()