Newer
Older
navi-1 / tests / unit / tools / test_content_publish.py
@Eugene Sukhodolskiy Eugene Sukhodolskiy on 30 Apr 3 KB Add artifact source previews
"""Unit tests for content_publish tool."""

import pytest

import navi.tools.content_publish as content_publish_mod
from navi.tools.base import current_session_id
from navi.tools.content_publish import ContentPublishTool


class TestContentPublishTool:
    @pytest.fixture
    def tool(self, monkeypatch, tmp_path):
        monkeypatch.setattr(content_publish_mod.settings, "session_files_dir", str(tmp_path / "sessions"))
        token = current_session_id.set("sess-1")
        try:
            yield ContentPublishTool()
        finally:
            current_session_id.reset(token)

    async def test_requires_active_session(self):
        token = current_session_id.set(None)
        try:
            result = await ContentPublishTool().execute({"filename": "logo.svg"})
        finally:
            current_session_id.reset(token)

        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"})

        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"})

        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",
        })

        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",
        })

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