a2a-source-edit: write tests/test_full_stack_contract.py
This commit is contained in:
@@ -1,7 +1,18 @@
|
||||
import asyncio
|
||||
import base64
|
||||
from pathlib import Path
|
||||
|
||||
from a2a_pack.auth import PlatformUserAuth
|
||||
from a2a_pack.cli.local import load_local_project
|
||||
from a2a_pack.context import LocalRunContext
|
||||
|
||||
from agent import (
|
||||
BrowserDocument,
|
||||
DocumentRequest,
|
||||
HighUtilityOnePageStartupsWE3c73,
|
||||
OUTPUT_FILENAME,
|
||||
_decode_browser_document,
|
||||
)
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
@@ -11,20 +22,79 @@ def test_full_stack_product_contract():
|
||||
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")
|
||||
migration = (ROOT / "db" / "migrations" / "001_app_records.sql").read_text(encoding="utf-8")
|
||||
|
||||
assert "frontend:" in manifest and "mount: /app" in manifest
|
||||
assert "auth: inherit" in manifest
|
||||
assert "resources:" in manifest and "databases:" in manifest
|
||||
assert "migrations:" in manifest and "db/migrations" in manifest
|
||||
assert "runtime:" in manifest and "account_access:" 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 "ctx.write_artifact" in source and "ctx.emit_artifact" in source
|
||||
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"
|
||||
|
||||
migrations = list((ROOT / "db" / "migrations").glob("*.sql"))
|
||||
assert migrations and all(path.read_text(encoding="utf-8").strip() for path in migrations)
|
||||
assert "DATABASE_URL" not in frontend and "A2A_LITELLM" not in frontend
|
||||
assert "CREATE TABLE IF NOT EXISTS execution_receipts" in migration
|
||||
|
||||
card = load_local_project(ROOT).agent_cls().card()
|
||||
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.required is True
|
||||
assert card.runtime.account_access.platform_skill_calls == 3
|
||||
skill_names = {skill.name for skill in card.skills}
|
||||
assert {"generate_document", "validate_browser_upload", "generate_document_from_upload"}.issubset(skill_names)
|
||||
|
||||
|
||||
def test_upload_bridge_validation_success_and_failure():
|
||||
good = BrowserDocument(
|
||||
filename="notes.txt",
|
||||
media_type="text/plain",
|
||||
data_base64=base64.b64encode(b"leasing traffic steady; vendor delay on two turns").decode("ascii"),
|
||||
)
|
||||
parsed = _decode_browser_document(good)
|
||||
assert parsed.status == "ok"
|
||||
assert "leasing traffic" in parsed.extracted_text
|
||||
|
||||
bad = BrowserDocument(filename="notes.txt", media_type="text/plain", data_base64="not-base64!!!")
|
||||
rejected = _decode_browser_document(bad)
|
||||
assert rejected.status == "validation_error"
|
||||
assert "base64" in rejected.message
|
||||
|
||||
|
||||
def test_generate_document_smoke_returns_preview_and_artifact(monkeypatch):
|
||||
monkeypatch.delenv("DATABASE_URL", raising=False)
|
||||
agent = HighUtilityOnePageStartupsWE3c73()
|
||||
ctx = LocalRunContext(
|
||||
auth=PlatformUserAuth(sub="user-123", user_id=123, email="pm@example.com"),
|
||||
task_id="test-task",
|
||||
)
|
||||
request = DocumentRequest(
|
||||
client_name="Northstar Property Group",
|
||||
property_name="Maple Ridge Apartments",
|
||||
property_type="multifamily",
|
||||
city="Austin",
|
||||
goal="owner update",
|
||||
intake=(
|
||||
"Owner wants a concise update on leasing momentum, delayed make-readies, "
|
||||
"and resident communication. Traffic is steady but follow-up is inconsistent."
|
||||
),
|
||||
tone="professional",
|
||||
)
|
||||
|
||||
result = asyncio.run(agent.generate_document(ctx, request))
|
||||
|
||||
assert result.document is not None
|
||||
assert result.document.filename == OUTPUT_FILENAME
|
||||
assert result.document.media_type == "text/markdown"
|
||||
assert result.document_preview.startswith("# Owner Update: Maple Ridge Apartments")
|
||||
assert OUTPUT_FILENAME in ctx.artifacts
|
||||
assert result.persisted_receipt is False
|
||||
assert result.status == "persistence_warning"
|
||||
|
||||
Reference in New Issue
Block a user