From e313802a15de6e5cdcc69ef07e1ed86fa7bdd6e3 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 9 May 2026 12:35:58 -0400 Subject: [PATCH] fix(serialization): Fix Path serialization in events and thread-local fallback in ai_client --- tests/smoke_status_hook.py | 35 ++++++++++++++++++++++++++++ tests/test_event_serialization.py | 38 +++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 tests/smoke_status_hook.py create mode 100644 tests/test_event_serialization.py diff --git a/tests/smoke_status_hook.py b/tests/smoke_status_hook.py new file mode 100644 index 0000000..cd51f00 --- /dev/null +++ b/tests/smoke_status_hook.py @@ -0,0 +1,35 @@ +import pytest +import time +import sys +import os + +# Ensure project root is in path +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +from src.api_hook_client import ApiHookClient + +def wait_for_value(client, field, expected, timeout=5): + """Polls the GUI state until a field matches the expected value.""" + start = time.time() + while time.time() - start < timeout: + val = client.get_value(field) + if val == expected: + return True + time.sleep(0.5) + return False + +@pytest.mark.smoke +def test_status_hook(live_gui) -> None: + """Smoke test for setting and getting ai_status and mma_status via ApiHookClient.""" + client = ApiHookClient() + assert client.wait_for_server(timeout=10) + + # 1. Set ai_status to 'hook_test' + client.set_value('ai_status', 'hook_test') + # 2. Verify via get_value('ai_status') == 'hook_test' (with retry) + assert wait_for_value(client, 'ai_status', 'hook_test'), f"Failed to set ai_status to hook_test. Current value: {client.get_value('ai_status')}" + + # 3. Set mma_status to 'hook_mma_test' + client.set_value('mma_status', 'hook_mma_test') + # 4. Verify via get_value('mma_status') == 'hook_mma_test' (with retry) + assert wait_for_value(client, 'mma_status', 'hook_mma_test'), f"Failed to set mma_status to hook_mma_test. Current value: {client.get_value('mma_status')}" diff --git a/tests/test_event_serialization.py b/tests/test_event_serialization.py new file mode 100644 index 0000000..3fb8608 --- /dev/null +++ b/tests/test_event_serialization.py @@ -0,0 +1,38 @@ +import json +from pathlib import Path +from src.events import UserRequestEvent + +def test_user_request_event_serialization(): + # Setup payload with nested Path objects + file_items = [ + {"path": Path("some/file.txt"), "mtime": 1234.5}, + {"path": Path("another/path"), "metadata": {"sub_path": Path("sub/path")}} + ] + base_dir = Path("C:/projects/test") + + event = UserRequestEvent( + prompt="Test prompt", + stable_md="# Context", + file_items=file_items, + disc_text="Discussion history", + base_dir=str(base_dir) + ) + + # Execute serialization + result = event.to_dict() + + # Verify no Path objects remain + assert isinstance(result["file_items"][0]["path"], str) + assert result["file_items"][0]["path"] == str(Path("some/file.txt")) + assert isinstance(result["file_items"][1]["metadata"]["sub_path"], str) + assert result["file_items"][1]["metadata"]["sub_path"] == str(Path("sub/path")) + + # Verify JSON serializability + try: + json.dumps(result) + except (TypeError, OverflowError) as e: + assert False, f"Result not JSON serializable: {e}" + +if __name__ == "__main__": + test_user_request_event_serialization() + print("Test passed!")