test(cron): cover absolute skill path normalization (#59824)

Add unit tests for normalize_skill_lookup_name and a cron scheduler
regression that absolute paths under the skills dir reach skill_view as
relative lookups.
This commit is contained in:
HexLab98 2026-07-07 02:59:03 +07:00 committed by kshitij
parent 62972060ca
commit e7082ea99f
2 changed files with 64 additions and 0 deletions

View file

@ -333,3 +333,42 @@ class TestSkillMatchesPlatformTermux:
"agent.skill_utils.is_termux", return_value=False
):
assert skill_matches_platform(fm) is True
class TestNormalizeSkillLookupName:
def test_relative_path_unchanged(self, tmp_path, monkeypatch):
from agent.skill_utils import normalize_skill_lookup_name
monkeypatch.setattr("agent.skill_utils.get_skills_dir", lambda: tmp_path / "skills")
assert normalize_skill_lookup_name("foo/bar") == "foo/bar"
def test_absolute_under_skills_dir_becomes_relative(self, tmp_path, monkeypatch):
from agent.skill_utils import normalize_skill_lookup_name
skills_dir = tmp_path / "skills"
skill_dir = skills_dir / "category" / "my-skill"
skill_dir.mkdir(parents=True)
monkeypatch.setattr("agent.skill_utils.get_skills_dir", lambda: skills_dir)
assert normalize_skill_lookup_name(str(skill_dir)) == "category/my-skill"
def test_absolute_via_symlink_uses_lexical_relative_path(self, tmp_path, monkeypatch):
from agent.skill_utils import normalize_skill_lookup_name
skills_dir = tmp_path / "skills"
skills_dir.mkdir()
external = tmp_path / "external" / "my-skill"
external.mkdir(parents=True)
link = skills_dir / "my-skill"
try:
link.symlink_to(external)
except OSError:
pytest.skip("Symlinks not supported")
monkeypatch.setattr("agent.skill_utils.get_skills_dir", lambda: skills_dir)
assert normalize_skill_lookup_name(str(link)) == "my-skill"
def test_untrusted_absolute_returned_unchanged(self, tmp_path, monkeypatch):
from agent.skill_utils import normalize_skill_lookup_name
monkeypatch.setattr("agent.skill_utils.get_skills_dir", lambda: tmp_path / "skills")
outside = str(tmp_path / "outside" / "skill")
assert normalize_skill_lookup_name(outside) == outside

View file

@ -2885,6 +2885,31 @@ class TestBuildJobPromptMissingSkill:
assert "go" in result
class TestBuildJobPromptAbsoluteSkillPath:
"""Cron jobs may store absolute skill paths; normalize before skill_view."""
def test_absolute_skill_path_normalized_before_skill_view(self, tmp_path):
skills_dir = tmp_path / "skills"
skill_dir = skills_dir / "alpha-skill"
skill_dir.mkdir(parents=True)
(skill_dir / "SKILL.md").write_text("# Alpha\nDo alpha.")
absolute_path = str(skill_dir)
seen_names: list[str] = []
def _skill_view(name: str) -> str:
seen_names.append(name)
if name == "alpha-skill":
return json.dumps({"success": True, "content": "# Alpha\nDo alpha."})
return json.dumps({"success": False, "error": f"Skill '{name}' not found."})
with patch("agent.skill_utils.get_skills_dir", return_value=skills_dir), \
patch("tools.skills_tool.skill_view", side_effect=_skill_view):
result = _build_job_prompt({"skills": [absolute_path], "prompt": "go"})
assert seen_names == ["alpha-skill"]
assert "Do alpha." in result
class TestBuildJobPromptBumpUse:
"""Verify that cron jobs bump skill usage counters so the curator sees them as active."""