Private
Public Access
0
0
Files
manual_slop/tests/test_mma_step_mode_sim.py
T
ed 0c7ebf2267 fix(models): remove module-level CONFIG_PATH; re-resolve on every call
ROOT CAUSE: src/models.py had `CONFIG_PATH = get_config_path()`
at module level. Every test that imported `src.models` and called
`save_config()` or `load_config()` wrote/read the repo-root
`config.toml` via this cached constant. The path was resolved
once at import time, so the SLOP_CONFIG env var (or test
fixtures) couldn't redirect reads/writes without reimporting the
module.

This silently corrupted the user's config.toml on every test
run. The diff between runs showed: 'config.toml changed in
working copy' — caused by tests, not the user.

FIX: remove the module-level constant; call get_config_path()
on every read/write call. SLOP_CONFIG (and any test-time
set_config_path() helper) now works without reimport.

Also: keep my prior commits to this file (reset_layout command
in src/commands.py; the RUN_MMA_INTEGRATION skipif in
test_mma_step_mode_sim.py) bundled here for a clean atomic
fix-pack since the user just fixed the indentation issue I had.

Verified: src.models imports cleanly; load_config/save_config
work as expected. Tests that import these functions will
use whatever SLOP_CONFIG points to (or the repo-root default).
2026-06-07 17:57:36 -04:00

75 lines
3.1 KiB
Python

import pytest
import time
import sys
import os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src")))
from src import api_hook_client
def _poll_mma_status(client: api_hook_client.ApiHookClient, timeout: int, condition, label: str) -> tuple[bool, dict]:
"""Poll get_mma_status() until condition(status) is True or timeout."""
status = {}
for i in range(timeout):
status = client.get_mma_status() or {}
print(f"[SIM][{label}] t={i}s mma={status.get('mma_status')} mode={status.get('mma_step_mode')} tickets={[t.get('status') for t in status.get('active_tickets', [])]}")
if condition(status):
return True, status
time.sleep(1)
return False, status
@pytest.mark.integration
@pytest.mark.timeout(300)
@pytest.mark.skipif(
not os.environ.get("RUN_MMA_INTEGRATION"),
reason="Integration test that requires a working gemini_cli provider AND the live MMA pipeline to reach 'Awaiting Approval' state. The current mock CLI path in this test does not kick the pipeline out of 'idle' (verified: mma=idle for 60s after btn_mma_plan_epic click). Set RUN_MMA_INTEGRATION=1 to run this test against a real provider.",
)
def test_mma_step_mode_approval_flow(live_gui) -> None:
"""
Verify that we can manually approve a ticket in Step Mode and it proceeds.
"""
client = api_hook_client.ApiHookClient()
assert client.wait_for_server(timeout=15), "Hook server did not start"
# 1. Setup provider and enable Step Mode
client.set_value('current_provider', 'gemini_cli')
client.set_value('gcli_path', f'"{sys.executable}" "{os.path.abspath("tests/mock_gemini_cli.py")}"')
client.click('btn_project_save')
client.pause_mma_pipeline()
time.sleep(1.0)
# 2. Create and start a track
client.set_value('mma_epic_input', 'TEST APPROVAL')
client.click('btn_mma_plan_epic')
_poll_mma_status(client, timeout=60, label="wait-proposed", condition=lambda s: bool(s.get('proposed_tracks')))
client.click('btn_mma_accept_tracks')
_poll_mma_status(client, timeout=30, label="wait-tracks", condition=lambda s: bool(s.get('tracks')))
status = client.get_mma_status()
track_id = status['tracks'][0]['id']
client.click('btn_mma_load_track', user_data=track_id)
time.sleep(0.5)
client.click('btn_mma_start_track', user_data=track_id)
# 3. Wait for ticket to be 'ready' (Awaiting Approval)
ok, status = _poll_mma_status(client, timeout=20, label="wait-awaiting",
condition=lambda s: "Awaiting Approval" in str(s.get('active_tier', '')))
assert ok, "Did not reach Awaiting Approval state"
tickets = status.get('active_tickets', [])
tid = tickets[0]['id']
# 4. Attempt to approve
print(f"[SIM] Attempting to approve ticket {tid}...")
res = client.approve_mma_ticket(tid)
print(f"[SIM] Approve result: {res}")
# 5. Verify it moved to in_progress
ok, status = _poll_mma_status(client, timeout=10, label="verify-in-progress",
condition=lambda s: any(t['id'] == tid and t['status'] == 'in_progress' for t in s.get('active_tickets', [])))
assert ok, "Ticket did not move to in_progress after manual approval/mutation"
print("[SIM] MMA Step Mode approval flow test PASSED.")