|
|
| import pytest |
| from sqlalchemy import select |
| from app.models import AllocationRun, Assignment, DecisionLog, AllocationRunStatus |
|
|
| @pytest.mark.asyncio |
| async def test_full_allocation_workflow(client, allocation_request, db_session, active_config): |
| """ |
| E2E: POST /allocate -> verify agents -> check outputs |
| """ |
| |
| response = await client.post("/api/v1/allocate", json=allocation_request) |
| assert response.status_code == 200, f"Allocation failed: {response.text}" |
| |
| data = response.json() |
| assert "allocation_run_id" in data |
| assert "global_fairness" in data |
| |
| |
| assert "assignments" in data |
| assert len(data["assignments"]) == 50 |
| |
| |
| result = await db_session.execute(select(AllocationRun)) |
| runs = result.scalars().all() |
| assert len(runs) == 1 |
| run = runs[0] |
| |
| assert run.status == AllocationRunStatus.SUCCESS |
| assert run.num_drivers == 50 |
| assert run.finished_at is not None |
| |
| |
| logs_result = await db_session.execute( |
| select(DecisionLog) |
| .where(DecisionLog.allocation_run_id == run.id) |
| .order_by(DecisionLog.created_at) |
| ) |
| logs = logs_result.scalars().all() |
| agent_steps = [log.agent_name for log in logs] |
| |
| |
| expected_agents = ["ML_EFFORT", "ROUTE_PLANNER", "FAIRNESS_MANAGER", |
| "DRIVER_LIAISON", "EXPLAINABILITY"] |
| |
| for agent in expected_agents: |
| assert agent in agent_steps, f"Missing agent: {agent}" |
| |
| |
| assign_result = await db_session.execute( |
| select(Assignment).where(Assignment.allocation_run_id == run.id) |
| ) |
| assignments = assign_result.scalars().all() |
| assert len(assignments) == 50 |
| |
| |
| fairness = data["global_fairness"] |
| |
| assert fairness["gini_index"] < 0.45 |
| assert fairness["std_dev"] < 35.0 |
|
|
| @pytest.mark.asyncio |
| async def test_assignments_have_explanations(client, allocation_request, active_config): |
| """Verify that all assignments have explanations.""" |
| response = await client.post("/api/v1/allocate", json=allocation_request) |
| assert response.status_code == 200 |
| data = response.json() |
| |
| for assignment in data["assignments"]: |
| assert assignment["explanation"] is not None |
| assert len(assignment["explanation"]) > 10 |
| |
| @pytest.mark.asyncio |
| async def test_allocation_run_persistence(client, allocation_request, db_session, active_config): |
| """Verify detailed persistence of allocation run.""" |
| response = await client.post("/api/v1/allocate", json=allocation_request) |
| run_id = response.json()["allocation_run_id"] |
| |
| result = await db_session.execute( |
| select(AllocationRun).where(AllocationRun.id == run_id) |
| ) |
| run = result.scalar_one() |
| |
| assert run.global_gini_index is not None |
| assert run.global_std_dev is not None |
| assert run.num_packages > 0 |
| assert run.num_routes > 0 |
|
|