Spaces:
Paused
Paused
File size: 8,138 Bytes
b484b4d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | """
Launch Desk — Agent & Tool Tests
================================
Pytest tests that verify the agent has 4 tools registered and that each
tool returns the expected structure.
Because @function_tool wraps functions in a FunctionTool dataclass, we
access the original callable via `tool.on_invoke_tool._get_wrapped_callable()`.
"""
import pytest
from server.agent import agent
from server.tools import (
extract_tasks,
check_readiness,
generate_checklist,
draft_copy,
)
# ---------------------------------------------------------------------------
# Helper: get the original wrapped callable from a FunctionTool
# ---------------------------------------------------------------------------
def _get_callable(tool):
"""Extract the original Python function from a @function_tool wrapper."""
return tool.on_invoke_tool._get_wrapped_callable()
# ---------------------------------------------------------------------------
# Test: agent has 4 tools registered
# ---------------------------------------------------------------------------
def test_agent_has_four_tools():
"""The Launch Planner agent should have exactly 4 tools registered."""
assert agent is not None
assert agent.name == "Launch Planner"
assert agent.tools is not None
assert len(agent.tools) == 4, f"Expected 4 tools, got {len(agent.tools)}"
def test_agent_has_expected_tool_names():
"""The agent should have tools with the expected names."""
tool_names = {t.name for t in agent.tools}
expected = {"extract_tasks", "check_readiness", "generate_checklist", "draft_copy"}
assert tool_names == expected, f"Expected {expected}, got {tool_names}"
# ---------------------------------------------------------------------------
# Test: extract_tasks returns expected structure
# ---------------------------------------------------------------------------
def test_extract_tasks_returns_list_of_dicts():
"""extract_tasks should return a list of dicts with task/priority/owner/deadline."""
fn = _get_callable(extract_tasks)
brief = "We are launching a new API with backend, QA testing, and marketing campaign"
result = fn(brief)
assert isinstance(result, list)
assert len(result) > 0
for task in result:
assert isinstance(task, dict)
assert "task" in task
assert "priority" in task
assert "owner" in task
assert "deadline" in task
def test_extract_tasks_handles_empty_brief():
"""extract_tasks should handle an empty brief gracefully."""
fn = _get_callable(extract_tasks)
result = fn("")
assert isinstance(result, list)
assert len(result) > 0
assert "task" in result[0]
def test_extract_tasks_priority_values():
"""All priorities should be high, medium, or low."""
fn = _get_callable(extract_tasks)
result = fn("API, QA, docs, marketing, support, security, pricing, analytics, design, legal")
valid_priorities = {"high", "medium", "low"}
for task in result:
assert task["priority"] in valid_priorities
# ---------------------------------------------------------------------------
# Test: check_readiness returns expected structure
# ---------------------------------------------------------------------------
def test_check_readiness_returns_dict():
"""check_readiness should return a dict with ready/score/gaps."""
fn = _get_callable(check_readiness)
tasks = "code freeze, QA testing, marketing campaign, documentation, support staffing"
result = fn(tasks, "2026-10-01")
assert isinstance(result, dict)
assert "ready" in result
assert "score" in result
assert "gaps" in result
assert isinstance(result["ready"], bool)
assert isinstance(result["score"], int)
assert isinstance(result["gaps"], list)
def test_check_readiness_high_score_when_covered():
"""check_readiness should give a high score when all rubric areas are covered."""
fn = _get_callable(check_readiness)
tasks = "code freeze, QA testing, marketing campaign, documentation, support staffing"
result = fn(tasks, "2026-10-01")
assert result["score"] >= 80, f"Expected high score, got {result['score']}"
def test_check_readiness_low_score_when_gaps():
"""check_readiness should give a low score when rubric areas are missing."""
fn = _get_callable(check_readiness)
tasks = "just some random text with no keywords"
result = fn(tasks, "2026-10-01")
assert result["score"] < 100
assert len(result["gaps"]) > 0
# ---------------------------------------------------------------------------
# Test: generate_checklist returns expected structure
# ---------------------------------------------------------------------------
def test_generate_checklist_returns_list_of_dicts():
"""generate_checklist should return a list of {owner, items} dicts."""
fn = _get_callable(generate_checklist)
import json
tasks_json = json.dumps([
{"task": "Freeze code", "owner": "Engineering", "priority": "high", "deadline": "T-14"},
{"task": "QA testing", "owner": "QA", "priority": "high", "deadline": "T-7"},
{"task": "Marketing campaign", "owner": "Marketing", "priority": "high", "deadline": "T-5"},
])
result = fn(tasks_json)
assert isinstance(result, list)
assert len(result) > 0
for checklist in result:
assert isinstance(checklist, dict)
assert "owner" in checklist
assert "items" in checklist
assert isinstance(checklist["items"], list)
assert len(checklist["items"]) > 0
for item in checklist["items"]:
assert isinstance(item, str)
def test_generate_checklist_includes_launch_lead():
"""generate_checklist should include a Launch Lead checklist."""
fn = _get_callable(generate_checklist)
result = fn("[]")
owners = [c["owner"] for c in result]
assert "Launch Lead" in owners
def test_generate_checklist_groups_by_owner():
"""generate_checklist should group tasks by owner."""
import json
fn = _get_callable(generate_checklist)
tasks_json = json.dumps([
{"task": "Task A", "owner": "Engineering"},
{"task": "Task B", "owner": "Engineering"},
{"task": "Task C", "owner": "Marketing"},
])
result = fn(tasks_json)
owners = {c["owner"] for c in result}
assert "Engineering" in owners
assert "Marketing" in owners
# ---------------------------------------------------------------------------
# Test: draft_copy returns expected structure
# ---------------------------------------------------------------------------
def test_draft_copy_returns_dict():
"""draft_copy should return a dict with headline/body/cta."""
fn = _get_callable(draft_copy)
result = fn("email", "LaunchDesk Pro", "enterprise DevOps teams")
assert isinstance(result, dict)
assert "headline" in result
assert "body" in result
assert "cta" in result
assert isinstance(result["headline"], str)
assert isinstance(result["body"], str)
assert isinstance(result["cta"], str)
def test_draft_copy_channel_specific():
"""draft_copy should produce different copy for different channels."""
fn = _get_callable(draft_copy)
email = fn("email", "ProductX", "developers")
twitter = fn("twitter", "ProductX", "developers")
assert email["headline"] != twitter["headline"], "Copy should differ by channel"
def test_draft_copy_includes_product_and_audience():
"""draft_copy should reference the product name and audience."""
fn = _get_callable(draft_copy)
result = fn("email", "MyProduct", "data scientists")
assert "MyProduct" in result["headline"] or "MyProduct" in result["body"]
assert "data scientists" in result["headline"] or "data scientists" in result["body"]
def test_draft_copy_handles_unknown_channel():
"""draft_copy should handle an unknown channel gracefully."""
fn = _get_callable(draft_copy)
result = fn("radio", "ProductX", "general audience")
assert isinstance(result, dict)
assert "headline" in result
assert "body" in result
assert "cta" in result
|