ctx / src /tests /test_dashboard_entities.py
Stevesolun's picture
Sync ctx 275ea32 (part 3)
7d83b2a verified
Raw
History Blame Contribute Delete
2.91 kB
from __future__ import annotations
from pathlib import Path
from typing import Literal
from ctx import dashboard_entities
from ctx.core.quality.skillspector_service import SkillSpectorResult
from ctx.monitor import testing as monitor_testing
class _NoopLock:
def __enter__(self) -> None:
return None
def __exit__(self, *_exc: object) -> Literal[False]:
return False
def test_skill_upsert_requires_security_gate_before_write(tmp_path: Path) -> None:
writes: list[tuple[Path, str]] = []
queued: list[tuple[str, str, Path, str, str]] = []
def fail_scan(_slug: str, _content: str) -> tuple[bool, str]:
return False, "SkillSpector security scan did not pass: findings"
deps = dashboard_entities.EntityCrudDeps(
is_safe_slug=lambda value: value == "unsafe-skill",
normalize_entity_type=lambda value: "skill" if value == "skill" else None,
wiki_entity_detail=lambda _slug, _etype: None,
wiki_entity_target_path=lambda slug, _etype: tmp_path / f"{slug}.md",
wiki_entity_path=lambda _slug, _etype: None,
iter_wiki_entity_paths=lambda _etype: [],
read_manifest=lambda: {"load": []},
perform_unload=lambda _slug, _etype: (True, "unloaded"),
queue_entity_refresh=lambda *args: queued.append(args), # type: ignore[arg-type]
file_lock=lambda _path: _NoopLock(),
write_entity_text=lambda path, content: writes.append((path, content)),
parse_frontmatter=lambda text: ({}, text),
frontmatter_tags=lambda _value: [],
frontmatter_text=lambda value: str(value or ""),
display_slug=lambda value: value,
display_label=lambda value: str(value),
entity_wiki_href=lambda slug, _etype: f"/wiki/{slug}?type=skill",
scan_skill_content=fail_scan,
)
ok, detail = dashboard_entities.upsert_wiki_entity(
{
"slug": "unsafe-skill",
"entity_type": "skill",
"title": "Unsafe Skill",
"body": "# Unsafe\n",
},
deps=deps,
)
assert ok is False
assert "SkillSpector" in detail
assert writes == []
assert queued == []
def test_monitor_entity_deps_scan_manual_skill_upserts(monkeypatch) -> None:
seen: list[tuple[str, str]] = []
def fake_scan(slug: str, content: str) -> SkillSpectorResult:
seen.append((slug, content))
return SkillSpectorResult(
status="findings",
command=["skillspector", "scan"],
exit_code=1,
output="prompt injection",
)
monkeypatch.setattr(monitor_testing, "run_skillspector_scan_text", fake_scan)
ok, detail = monitor_testing.scan_skill_entity_content("unsafe-skill", "# Unsafe\n")
assert ok is False
assert "SkillSpector security scan did not pass: findings" in detail
assert seen == [("unsafe-skill", "# Unsafe\n")]