80 lines
3.4 KiB
Python
80 lines
3.4 KiB
Python
import asyncio
|
|
from pathlib import Path
|
|
|
|
from a2a_pack import LocalRunContext, PlatformUserAuth
|
|
from a2a_pack.cli.local import load_local_project
|
|
|
|
import agent
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def test_full_stack_product_contract():
|
|
manifest = (ROOT / "a2a.yaml").read_text(encoding="utf-8")
|
|
source = (ROOT / "agent.py").read_text(encoding="utf-8")
|
|
frontend = (ROOT / "frontend" / "src" / "App.jsx").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 "public: false" in manifest
|
|
assert "resources:" in manifest and "databases:" in manifest
|
|
assert "runtime:" in manifest and "platform_skill_calls: 3" in manifest
|
|
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 "Skill runner" not in frontend, "replace generic scaffold with 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
|
|
assert "DATABASE_URL" not in frontend
|
|
|
|
migrations = list((ROOT / "db" / "migrations").glob("*.sql"))
|
|
assert migrations and all(path.read_text(encoding="utf-8").strip() for path in migrations)
|
|
|
|
card = load_local_project(ROOT).agent_cls().card()
|
|
skills = {skill.name: skill for skill in card.skills}
|
|
assert {"build_dashboard", "list_history", "scheduled_rollup"}.issubset(skills)
|
|
assert "updates_text" in skills["build_dashboard"].input_schema["properties"]
|
|
assert "run_key" in skills["scheduled_rollup"].input_schema["properties"]
|
|
databases = card.runtime.platform_resources.databases
|
|
assert databases, "live Agent Card must declare its managed database"
|
|
assert databases[0].migrations is not None
|
|
assert databases[0].migrations.path == "db/migrations"
|
|
assert card.runtime.account_access.platform_skill_calls == 3
|
|
|
|
|
|
def test_deterministic_analysis_fixture():
|
|
rows = agent._analyze_updates(agent.DEFAULT_UPDATES)
|
|
assert len(rows) == 4
|
|
exceptions = agent._build_exceptions(rows)
|
|
trends = agent._build_trends(rows)
|
|
assert trends["status_counts"] == {"green": 2, "yellow": 1, "red": 1}
|
|
assert trends["average_utilization"] == 78.8
|
|
assert len(exceptions) == 2
|
|
assert {item["client"] for item in exceptions} == {"Beacon CRM", "Cedar Mobile"}
|
|
csv_text = agent._rows_to_csv(rows)
|
|
assert "agency-ops-dashboard" not in csv_text
|
|
assert "Acme Portal" in csv_text
|
|
|
|
|
|
def test_missing_database_returns_setup_required():
|
|
async def run():
|
|
app = agent.ProductionProofV116HighUtili72551()
|
|
ctx = LocalRunContext(
|
|
auth=PlatformUserAuth(sub="stable-user", user_id=123, email="dev@example.local"),
|
|
task_id="test-dashboard",
|
|
)
|
|
result = await app.invoke("build_dashboard", ctx)
|
|
return result, ctx
|
|
|
|
result, ctx = asyncio.run(run())
|
|
assert result.status == "setup_required"
|
|
assert result.dashboard_data
|
|
assert result.artifact.name == "agency-ops-dashboard.csv"
|
|
assert result.artifact.media_type == "text/csv"
|
|
assert "DATABASE_URL" not in result.summary
|
|
assert "agency-ops-dashboard.csv" in ctx.artifacts
|