import os from pathlib import Path import pytest from a2a_pack import PlatformUserAuth from a2a_pack.cli.local import load_local_project import agent as agent_module from agent import GeneratesSvgVideoGame9jg9vdF0f510 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 "migrations:" in manifest and "db/migrations" in manifest assert "PlatformUserAuth" in source assert "AgentPlatformResources" in source and "AgentDatabase(" in source assert "Skill runner" not in frontend assert "generate_svg_asset" in frontend assert "Download SVG" in frontend assert "unwrapSkillResponse(payload)" 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() skill_names = {skill.name for skill in card.skills} assert {"generate_svg_asset", "list_recent_receipts"} <= skill_names 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" @pytest.mark.asyncio async def test_generate_svg_asset_smoke_without_database(monkeypatch): monkeypatch.delenv("DATABASE_URL", raising=False) auth = PlatformUserAuth(sub="stable-user", user_id=42, email="player@example.test") result = await GeneratesSvgVideoGame9jg9vdF0f510().local_invoke( "generate_svg_asset", auth=auth, asset_type="character", theme="forest knight", palette=["#22c55e", "#14532d", "#facc15"], size=96, style="pixel", variant_count=2, ) assert result.status == "ok" assert result.receipt_id.startswith("rcpt_") assert result.asset_id.startswith("asset_") assert result.receipt_persisted is False assert len(result.svg_assets) == 2 assert result.svg_assets[0]["svg"].startswith("= {"asset_type", "theme"} assert props["theme"]["maxLength"] == 80 assert props["size"]["maximum"] == 512 assert props["variant_count"]["maximum"] == 4 assert props["asset_type"]["enum"] == ["character", "enemy", "item", "tile", "icon", "projectile"] assert schema["additionalProperties"] is False