from datetime import UTC, datetime from unittest.mock import Mock from uuid import uuid4 from fastapi import FastAPI from fastapi.testclient import TestClient from modelforge_api.api.authorization import ( Principal, PrincipalRole, authenticate_operator_principal, ) from modelforge_api.api.routes.lab import get_lab_run_service, router from modelforge_api.domain.lab import LabExecutionRunResponse, LabInputSummary def start_body() -> dict[str, object]: return { "target": { name: str(uuid4()) for name in ( "deployment_candidate_id", "artifact_set_id", "runtime_profile_id", "compute_node_id", "execution_approval_id", ) }, "input": {"capability": "rag.embedding", "payload": {"input": "private-lab-canary"}}, "deployment_id": str(uuid4()), "experiment_route_id": str(uuid4()), } def harness(role: PrincipalRole) -> tuple[TestClient, Mock]: app = FastAPI() app.include_router(router) service = Mock() service.start.return_value = LabExecutionRunResponse( id=uuid4(), status="accepted", target_snapshot={"deployment_id": str(uuid4())}, input_summary=LabInputSummary(sha256="a" * 64, item_count=1, encoded_bytes=45), input_payload_expires_at=datetime.now(UTC), retention_seconds=300, created_at=datetime.now(UTC), ) app.dependency_overrides[authenticate_operator_principal] = lambda: Principal( "operator-one", role, "test" ) app.dependency_overrides[get_lab_run_service] = lambda: service return TestClient(app), service def test_operator_lab_start_route_is_registered_and_returns_accepted_run() -> None: client, service = harness(PrincipalRole.OPERATOR) response = client.post( "/api/v1/lab/runs", headers={"Idempotency-Key": "start-once"}, json=start_body(), ) assert response.status_code == 202 payload = response.json() assert payload["status"] == "accepted" assert payload["capability"] == "rag.embedding@1" assert "private-lab-canary" not in response.text assert response.headers["cache-control"] == "no-store" service.start.assert_called_once() assert service.start.call_args.kwargs["actor_subject"] == "operator-one" assert service.start.call_args.kwargs["idempotency_key"] == "start-once" def test_lab_run_start_requires_operator_role() -> None: client, service = harness(PrincipalRole.VIEWER) response = client.post( "/api/v1/lab/runs", headers={"Idempotency-Key": "start-viewer"}, json=start_body(), ) assert response.status_code == 403 service.start.assert_not_called() def test_lab_run_status_and_cancel_are_no_store_and_actor_scoped() -> None: client, service = harness(PrincipalRole.OPERATOR) run_id = service.start.return_value.id service.get.return_value = service.start.return_value service.cancel.return_value = service.start.return_value status_response = client.get(f"/api/v1/lab/runs/{run_id}") cancel_response = client.post(f"/api/v1/lab/runs/{run_id}/cancel") assert status_response.status_code == 200 assert cancel_response.status_code == 200 assert status_response.headers["cache-control"] == "no-store" assert cancel_response.headers["cache-control"] == "no-store" assert "payload_reference" not in status_response.text assert "private-lab-canary" not in status_response.text assert service.get.call_args.args == (run_id,) assert service.get.call_args.kwargs == {"actor_subject": "operator-one"} assert service.cancel.call_args.args == (run_id,) assert service.cancel.call_args.kwargs == {"actor_subject": "operator-one"}