Newer
Older
navi-1 / tests / unit / tools / test_content_publish.py
"""Unit tests for content_publish tool."""

import pytest

import navi.content_store as content_store_mod
import navi.session_files as session_files_mod
import navi.tools.content_publish as content_publish_mod
from navi.tools._internal.base import ToolContext
from navi.tools.content_publish import ContentPublishTool


class TestContentPublishTool:
    @pytest.fixture
    def tool(self, monkeypatch, tmp_path):
        from navi.config import Settings

        _test_settings = Settings(session_files_dir=str(tmp_path / "sessions"))
        monkeypatch.setattr(content_publish_mod, "settings", _test_settings)
        monkeypatch.setattr(session_files_mod, "settings", _test_settings)
        monkeypatch.setattr(content_store_mod, "settings", _test_settings)
        yield ContentPublishTool()

    async def test_requires_active_session(self):
        result = await ContentPublishTool().execute({"filename": "logo.svg"}, ctx=ToolContext(session_id=None))

        assert not result.success
        assert result.error == "no_session"

    async def test_missing_file_reports_session_dir(self, tool, tmp_path):
        result = await tool.execute({"filename": "missing.svg"}, ctx=ToolContext(session_id="sess-1"))

        assert not result.success
        assert result.error == "not_found"
        assert str(tmp_path / "sessions" / "sess-1") in result.output
        assert "SESSION_FILES_DIR" in result.output

    async def test_rejects_directory(self, tool, tmp_path):
        sess_dir = tmp_path / "sessions" / "sess-1"
        (sess_dir / "folder").mkdir(parents=True)

        result = await tool.execute({"filename": "folder"}, ctx=ToolContext(session_id="sess-1"))

        assert not result.success
        assert result.error == "not_a_file"

    async def test_strips_path_components_and_publishes(self, tool, monkeypatch, tmp_path):
        sess_dir = tmp_path / "sessions" / "sess-1"
        sess_dir.mkdir(parents=True)
        (sess_dir / "logo.svg").write_text("<svg></svg>")
        calls = []

        async def fake_publish(**kwargs):
            calls.append(kwargs)
            return {
                "id": "content-id",
                "url": "http://localhost:8000/sessions/sess-1/files/logo.svg",
                "filename": kwargs["filename"],
                "content_type": kwargs["content_type"] or "svg",
                "title": kwargs["title"] or kwargs["filename"],
            }

        monkeypatch.setattr(content_publish_mod, "publish", fake_publish)

        result = await tool.execute({
            "filename": "../logo.svg",
            "title": "Logo",
            "content_type": "svg",
        }, ctx=ToolContext(session_id="sess-1"))

        assert result.success
        assert calls == [{
            "session_id": "sess-1",
            "filename": "logo.svg",
            "title": "Logo",
            "content_type": "svg",
            "source_filename": None,
        }]
        assert result.metadata["filename"] == "logo.svg"

    async def test_passes_optional_source_filename(self, tool, monkeypatch, tmp_path):
        sess_dir = tmp_path / "sessions" / "sess-1"
        sess_dir.mkdir(parents=True)
        (sess_dir / "model.stl").write_text("solid model")
        (sess_dir / "model.scad").write_text("cube([1, 1, 1]);")
        calls = []

        async def fake_publish(**kwargs):
            calls.append(kwargs)
            return {
                "id": "content-id",
                "url": "http://localhost:8000/sessions/sess-1/files/model.stl",
                "filename": kwargs["filename"],
                "content_type": "stl",
                "title": kwargs["title"] or kwargs["filename"],
                "source_filename": kwargs["source_filename"],
                "source_url": "http://localhost:8000/sessions/sess-1/files/model.scad",
            }

        monkeypatch.setattr(content_publish_mod, "publish", fake_publish)

        result = await tool.execute({
            "filename": "model.stl",
            "source_filename": "model.scad",
        }, ctx=ToolContext(session_id="sess-1"))

        assert result.success
        assert calls[0]["source_filename"] == "model.scad"
        assert result.metadata["source_filename"] == "model.scad"