from pathlib import PurePosixPath import pytest from personal_mcp.registry.models.registry import DocsRegistry from personal_mcp.registry.models.registry import PromptRecord from personal_mcp.registry.models.registry import PromptSummaryRecord from personal_mcp.registry.models.registry import ReferenceRecord from personal_mcp.registry.models.registry import SkillRecord from personal_mcp.registry.models.registry import SkillSummaryRecord from personal_mcp.registry.read import read_docs_markdown_path from personal_mcp.registry.read import read_prompt_document from personal_mcp.registry.read import read_skill_document from personal_mcp.registry.read import read_skill_reference pytestmark = pytest.mark.unit def _make_registry() -> DocsRegistry: skill_path = PurePosixPath("skills/demo/SKILL.md") reference_path = PurePosixPath("skills/demo/references/guide.md") prompt_path = PurePosixPath("prompts/demo-prompt/PROMPT.md") index_path = PurePosixPath("index.md") reference = ReferenceRecord( ref_id="guide", uri="resource://skills/demo/references/guide", relpath=reference_path, mime_type="text/markdown", title="Guide", content="# guide", ) skill = SkillRecord( skill_id="demo", name="demo", description="demo skill", version="1.0.0", tags=("testing",), capabilities=("resource://skills/demo/document",), document_uri="resource://skills/demo/document", document_relpath=skill_path, document_content="# demo", references={"guide": reference}, ) prompt = PromptRecord( prompt_id="demo-prompt", name="demo-prompt", description="demo prompt", version="1.0.0", tags=("testing",), capabilities=("resource://prompts/demo-prompt/document",), arguments={}, document_uri="resource://prompts/demo-prompt/document", document_relpath=prompt_path, document_content="# prompt", ) return DocsRegistry( skills_by_id={skill.skill_id: skill}, skills_in_load_order=(skill.skill_id,), skills_summary_in_load_order=(SkillSummaryRecord.from_record(skill),), docs_markdown_by_path={index_path: "# index"}, docs_markdown_path_index=(index_path,), tag_to_skill_ids={"testing": (skill.skill_id,)}, capability_to_skill_ids={}, prompts_by_id={prompt.prompt_id: prompt}, prompts_in_load_order=(prompt.prompt_id,), prompts_summary_in_load_order=(PromptSummaryRecord.from_record(prompt),), tag_to_prompt_ids={"testing": (prompt.prompt_id,)}, ) def test_reads_docs_path_from_string_boundary() -> None: payload = read_docs_markdown_path(_make_registry(), "index.md") assert payload == { "uri": "resource://docs/index.md", "format": "markdown", "source_path": "docs/index.md", "content": "# index", } def test_rejects_non_posix_docs_path() -> None: with pytest.raises(ValueError, match="POSIX separators"): read_docs_markdown_path(_make_registry(), "skills\\demo\\SKILL.md") def test_serializes_record_paths_in_document_payloads() -> None: registry = _make_registry() assert read_skill_document(registry, "demo")["source_path"] == "docs/skills/demo/SKILL.md" assert read_skill_reference(registry, skill_id="demo", ref_id="guide")["source_path"] == ( "docs/skills/demo/references/guide.md" ) assert read_prompt_document(registry, "demo-prompt")["source_path"] == ("docs/prompts/demo-prompt/PROMPT.md")