import threading import time import requests import pytest from api_hook_client import ApiHookClient def test_api_ask_synchronous_flow(live_gui): """ Tests the full synchronous lifecycle of the /api/ask endpoint: 1. A client makes a blocking request. 2. An event is emitted with a unique request_id. 3. A separate agent responds to that request_id. 4. The original blocking request completes with the provided data. """ # The live_gui fixture starts the Manual Slop application with hooks on 8999. client = ApiHookClient("http://127.0.0.1:8999") # Drain existing events client.get_events() results = {"response": None, "error": None} def make_blocking_request(): try: # This POST will block until we call /api/ask/respond # Note: /api/ask returns {'status': 'ok', 'response': ...} resp = requests.post( "http://127.0.0.1:8999/api/ask", json={"prompt": "Should we proceed with the refactor?"}, timeout=10 ) results["response"] = resp.json() except Exception as e: results["error"] = str(e) # Start the request in a background thread t = threading.Thread(target=make_blocking_request) t.start() # Poll for the 'ask_received' event to find the generated request_id request_id = None start_time = time.time() while time.time() - start_time < 5: events = client.get_events() for ev in events: if ev.get("type") == "ask_received": request_id = ev.get("request_id") break if request_id: break time.sleep(0.1) assert request_id is not None, "Timed out waiting for 'ask_received' event" # Respond to the task via the respond endpoint expected_response = {"approved": True, "message": "Proceeding as requested."} resp = requests.post( "http://127.0.0.1:8999/api/ask/respond", json={ "request_id": request_id, "response": expected_response } ) assert resp.status_code == 200 # Join the thread and verify the original request received the correct data t.join(timeout=5) assert not t.is_alive(), "Background thread failed to unblock" assert results["error"] is None, f"Request failed: {results['error']}" # The /api/ask endpoint returns {'status': 'ok', 'response': expected_response} assert results["response"]["status"] == "ok" assert results["response"]["response"] == expected_response