CheddahBot/tests/test_clickup_runner/test_skill_map.py

152 lines
5.0 KiB
Python

"""Tests for clickup_runner.skill_map."""
import pytest
from clickup_runner.skill_map import (
SKILL_MAP,
SkillRoute,
get_route,
get_supported_task_types,
get_valid_stages,
)
class TestGetRoute:
def test_content_creation_run_cora(self):
route = get_route("Content Creation", "run_cora")
assert route is not None
assert route.handler == "autocora"
assert route.next_stage == "outline"
assert route.next_status == "review"
def test_content_creation_outline(self):
route = get_route("Content Creation", "outline")
assert route is not None
assert route.handler == "claude"
assert route.skill_file == "content_outline.md"
assert route.next_stage == "draft"
def test_content_creation_draft(self):
route = get_route("Content Creation", "draft")
assert route is not None
assert route.next_stage == "final"
assert route.max_turns == 20
def test_on_page_optimization_has_hidden_div(self):
route = get_route("On Page Optimization", "hidden div")
assert route is not None
assert route.skill_file == "content_hidden_div.md"
assert route.next_stage == "final"
def test_on_page_draft_goes_to_hidden_div(self):
route = get_route("On Page Optimization", "draft")
assert route is not None
assert route.next_stage == "hidden div"
def test_press_release_single_stage(self):
route = get_route("Press Release", "draft")
assert route is not None
assert route.skill_file == "press_release_prompt.md"
assert route.next_stage == "final"
assert route.next_status == "review"
def test_press_release_no_run_cora(self):
"""Press releases don't need Cora."""
route = get_route("Press Release", "run_cora")
assert route is None
def test_link_building_run_cora(self):
route = get_route("Link Building", "run_cora")
assert route is not None
assert route.handler == "autocora"
assert route.next_stage == "build"
def test_link_building_build(self):
route = get_route("Link Building", "build")
assert route is not None
assert route.handler == "claude"
assert route.skill_file == "linkbuilding.md"
def test_unknown_task_type_returns_none(self):
assert get_route("Banana Farming", "draft") is None
def test_unknown_stage_returns_none(self):
assert get_route("Content Creation", "nonexistent") is None
def test_stage_is_case_insensitive(self):
route = get_route("Content Creation", "RUN_CORA")
assert route is not None
assert route.handler == "autocora"
def test_stage_strips_whitespace(self):
route = get_route("Content Creation", " outline ")
assert route is not None
assert route.handler == "claude"
class TestGetValidStages:
def test_content_creation(self):
stages = get_valid_stages("Content Creation")
assert stages == ["run_cora", "outline", "draft"]
def test_on_page_optimization(self):
stages = get_valid_stages("On Page Optimization")
assert "hidden div" in stages
assert len(stages) == 4
def test_press_release(self):
stages = get_valid_stages("Press Release")
assert stages == ["draft"]
def test_link_building(self):
stages = get_valid_stages("Link Building")
assert stages == ["run_cora", "build"]
def test_unknown_type(self):
assert get_valid_stages("Nope") == []
class TestGetSupportedTaskTypes:
def test_returns_all_four(self):
types = get_supported_task_types()
assert "Content Creation" in types
assert "On Page Optimization" in types
assert "Press Release" in types
assert "Link Building" in types
assert len(types) == 4
class TestSkillRouteDataclass:
def test_defaults(self):
route = SkillRoute(next_stage="x", next_status="y")
assert route.handler == "claude"
assert route.skill_file == ""
assert route.tools == ""
assert route.max_turns == 10
def test_frozen(self):
route = SkillRoute(next_stage="x", next_status="y")
with pytest.raises(AttributeError):
route.next_stage = "z" # type: ignore[misc]
class TestAllRoutesHaveRequiredFields:
"""Every route in the map should be well-formed."""
@pytest.mark.parametrize(
"task_type,stage",
[
(tt, s)
for tt, stages in SKILL_MAP.items()
for s in stages
],
)
def test_route_has_required_fields(self, task_type, stage):
route = get_route(task_type, stage)
assert route is not None
assert route.next_stage, f"{task_type}/{stage} missing next_stage"
assert route.next_status, f"{task_type}/{stage} missing next_status"
if route.handler == "claude":
assert route.skill_file, f"{task_type}/{stage} missing skill_file"
assert route.tools, f"{task_type}/{stage} missing tools"