a2a-source-edit: write tests/test_full_stack_contract.py

This commit is contained in:
a2a-cloud
2026-07-19 19:58:25 +00:00
parent 2d43a16401
commit 658c764ed4

View File

@@ -1,7 +1,15 @@
import asyncio
from pathlib import Path from pathlib import Path
from a2a_pack import LocalRunContext, PlatformUserAuth
from a2a_pack.cli.local import load_local_project from a2a_pack.cli.local import load_local_project
from agent import (
BuildDashboardRequest,
ProductionProofV116HighUtili72553,
_analyze_updates,
_default_updates,
)
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
@@ -13,12 +21,20 @@ def test_full_stack_product_contract():
frontend_client = (ROOT / "frontend" / "src" / "a2a.js").read_text(encoding="utf-8") frontend_client = (ROOT / "frontend" / "src" / "a2a.js").read_text(encoding="utf-8")
assert "frontend:" in manifest and "mount: /app" in manifest assert "frontend:" in manifest and "mount: /app" in manifest
assert "public: false" in manifest
assert "resources:" in manifest and "databases:" in manifest assert "resources:" in manifest and "databases:" in manifest
assert "migrations:" in manifest and "db/migrations" in manifest assert "runtime:" in manifest and "max_runtime_seconds: 600" in manifest
assert "PlatformUserAuth" in source assert "PlatformUserAuth" in source
assert "AccountAccess(required=True, platform_skill_calls=3, after_trial=\"byok\")" in source
assert "AgentPlatformResources" in source and "AgentDatabase(" in source assert "AgentPlatformResources" in source and "AgentDatabase(" in source
assert "llm_provisioning" not in source
assert "Skill runner" not in frontend, "replace the generic scaffold with the product workflow" assert "Skill runner" not in frontend, "replace the generic scaffold with the product workflow"
assert "data-testid=\"agent-app\"" in frontend
assert "data-testid=\"agent-submit\"" in frontend
assert "data-testid=\"agent-result\"" in frontend
assert "data-testid=\"agent-download\"" in frontend
assert "unwrapInvokeResponse" in frontend_client, "unwrap the /invoke result envelope before rendering" assert "unwrapInvokeResponse" in frontend_client, "unwrap the /invoke result envelope before rendering"
assert "DATABASE_URL" not in frontend
migrations = list((ROOT / "db" / "migrations").glob("*.sql")) migrations = list((ROOT / "db" / "migrations").glob("*.sql"))
assert migrations and all(path.read_text(encoding="utf-8").strip() for path in migrations) assert migrations and all(path.read_text(encoding="utf-8").strip() for path in migrations)
@@ -28,3 +44,54 @@ def test_full_stack_product_contract():
assert databases, "live Agent Card must declare its managed database" assert databases, "live Agent Card must declare its managed database"
assert databases[0].migrations is not None assert databases[0].migrations is not None
assert databases[0].migrations.path == "db/migrations" assert databases[0].migrations.path == "db/migrations"
assert card.runtime.account_access.required is True
assert card.runtime.account_access.platform_skill_calls == 3
assert card.runtime.pricing.caller_pays_llm is False
def test_analysis_returns_dashboard_table_filters_trends_exceptions():
request = BuildDashboardRequest(updates=_default_updates())
analysis = _analyze_updates(request)
assert len(analysis["rows"]) >= 1
assert analysis["filters"]["owners"] == ["Mateo", "Nora", "Priya"]
assert any(item["metric"] == "pipeline_total" and item["value"] == 288000 for item in analysis["trends"])
assert [item["account"] for item in analysis["exceptions"]][:2] == ["Summit Retail", "Acme Manufacturing"]
def test_build_dashboard_without_database_returns_preview_artifact_and_setup_required(monkeypatch):
monkeypatch.delenv("DATABASE_URL", raising=False)
agent = ProductionProofV116HighUtili72553()
ctx = LocalRunContext(
auth=PlatformUserAuth(sub="user-123", user_id=123, email="dev@example.local"),
task_id="test-task",
)
result = asyncio.run(agent.invoke("build_dashboard", ctx, request=BuildDashboardRequest()))
assert result.status == "setup_required"
assert result.dashboard_data
assert result.artifact is not None
assert result.artifact.name == "sales-ops-dashboard.csv"
assert result.artifact.media_type == "text/csv"
assert "account,owner,stage" in result.artifact.content
assert "sales-ops-dashboard.csv" in ctx.artifacts
assert result.receipt_id.startswith("rcpt_")
def test_history_without_database_is_structured_setup_required(monkeypatch):
monkeypatch.delenv("DATABASE_URL", raising=False)
agent = ProductionProofV116HighUtili72553()
ctx = LocalRunContext(auth=PlatformUserAuth(sub="user-123", user_id=123))
result = asyncio.run(agent.invoke("list_dashboard_history", ctx, limit=1000))
assert result.status == "setup_required"
assert result.history == []
def test_public_tool_schemas_are_bounded_and_mcp_named():
card = ProductionProofV116HighUtili72553().card()
skill_names = {skill.name for skill in card.skills}
assert {"build_dashboard", "list_dashboard_history", "run_scheduled_snapshot"}.issubset(skill_names)
build_skill = next(skill for skill in card.skills if skill.name == "build_dashboard")
schema_text = str(build_skill.input_schema)
assert "maxItems" in schema_text or "max_length" in schema_text
assert "request" in build_skill.input_schema.get("properties", {})