- 将代码库中所有对 /mnt/user-data 的引用更改为 /home/yuxi/user-data。 - 更新测试用例以反映新的路径结构。 - 调整 Docker 配置以使用新路径。 - 修改文档以与新的路径约定保持一致。 - 增强沙盒配置器中文件读取操作的错误处理。 - 改进代理文件管理系统中的附件处理。
120 lines
4.2 KiB
Python
120 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
import io
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from yuxi.services import conversation_service as cs
|
|
|
|
|
|
class _DummyUpload:
|
|
def __init__(self, *, filename: str, content_type: str | None, data: bytes):
|
|
self.filename = filename
|
|
self.content_type = content_type
|
|
self._buffer = io.BytesIO(data)
|
|
|
|
async def read(self, size: int = -1) -> bytes:
|
|
return self._buffer.read(size)
|
|
|
|
async def seek(self, offset: int) -> int:
|
|
return self._buffer.seek(offset)
|
|
|
|
|
|
def test_build_attachment_storage_path_uses_thread_local_uploads_dir(tmp_path: Path, monkeypatch) -> None:
|
|
monkeypatch.setattr(cs.app_config, "save_dir", str(tmp_path))
|
|
|
|
virtual_path, host_path = cs._build_attachment_storage_path(
|
|
user_id="u-1",
|
|
thread_id="t-1",
|
|
file_name="demo.txt",
|
|
)
|
|
|
|
assert virtual_path == "/home/yuxi/user-data/uploads/attachments/demo.md"
|
|
assert host_path == tmp_path / "threads" / "t-1" / "user-data" / "uploads" / "attachments" / "demo.md"
|
|
|
|
|
|
def test_serialize_attachment_includes_original_file_fields() -> None:
|
|
serialized = cs.serialize_attachment(
|
|
{
|
|
"file_id": "f-1",
|
|
"file_name": "demo.txt",
|
|
"file_type": "text/plain",
|
|
"file_size": 5,
|
|
"status": "parsed",
|
|
"uploaded_at": "2026-03-25T00:00:00+00:00",
|
|
"path": "/home/yuxi/user-data/uploads/attachments/demo.md",
|
|
"artifact_url": "/api/chat/thread/t-1/artifacts/home/yuxi/user-data/uploads/attachments/demo.md",
|
|
"original_path": "/home/yuxi/user-data/uploads/demo.txt",
|
|
"original_artifact_url": "/api/chat/thread/t-1/artifacts/home/yuxi/user-data/uploads/demo.txt",
|
|
"minio_url": None,
|
|
}
|
|
)
|
|
|
|
assert serialized["path"] == "/home/yuxi/user-data/uploads/attachments/demo.md"
|
|
assert serialized["original_path"] == "/home/yuxi/user-data/uploads/demo.txt"
|
|
assert serialized["original_artifact_url"] == "/api/chat/thread/t-1/artifacts/home/yuxi/user-data/uploads/demo.txt"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_materialize_attachment_files_keeps_original_file_when_markdown_conversion_unsupported(
|
|
tmp_path: Path,
|
|
monkeypatch,
|
|
) -> None:
|
|
monkeypatch.setattr(cs.app_config, "save_dir", str(tmp_path))
|
|
|
|
upload = _DummyUpload(filename="demo.pdf", content_type="application/pdf", data=b"%PDF-test")
|
|
|
|
result = await cs._materialize_attachment_files(
|
|
thread_id="t-1",
|
|
upload=upload,
|
|
file_name="demo.pdf",
|
|
file_content=b"%PDF-test",
|
|
)
|
|
|
|
assert result["status"] == "uploaded"
|
|
assert result["path"] == "/home/yuxi/user-data/uploads/demo.pdf"
|
|
assert result["original_path"] == "/home/yuxi/user-data/uploads/demo.pdf"
|
|
assert (
|
|
tmp_path / "threads" / "t-1" / "user-data" / "uploads" / "demo.pdf"
|
|
).read_bytes() == b"%PDF-test"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_materialize_attachment_files_writes_markdown_copy_when_conversion_succeeds(
|
|
tmp_path: Path,
|
|
monkeypatch,
|
|
) -> None:
|
|
monkeypatch.setattr(cs.app_config, "save_dir", str(tmp_path))
|
|
|
|
async def _fake_convert(_upload):
|
|
return cs.ConversionResult(
|
|
file_id="f-1",
|
|
file_name="demo.txt",
|
|
file_type="text/plain",
|
|
file_size=5,
|
|
markdown="hello\nworld",
|
|
truncated=False,
|
|
)
|
|
|
|
monkeypatch.setattr(cs, "_convert_upload_to_markdown", _fake_convert)
|
|
|
|
upload = _DummyUpload(filename="demo.txt", content_type="text/plain", data=b"hello")
|
|
|
|
result = await cs._materialize_attachment_files(
|
|
thread_id="t-1",
|
|
upload=upload,
|
|
file_name="demo.txt",
|
|
file_content=b"hello",
|
|
)
|
|
|
|
assert result["status"] == "parsed"
|
|
assert result["path"] == "/home/yuxi/user-data/uploads/attachments/demo.md"
|
|
assert result["original_path"] == "/home/yuxi/user-data/uploads/demo.txt"
|
|
assert result["file_path"] == "/home/yuxi/user-data/uploads/attachments/demo.md"
|
|
assert result["markdown"] == "hello\nworld"
|
|
assert (tmp_path / "threads" / "t-1" / "user-data" / "uploads" / "demo.txt").read_bytes() == b"hello"
|
|
assert (
|
|
tmp_path / "threads" / "t-1" / "user-data" / "uploads" / "attachments" / "demo.md"
|
|
).read_text(encoding="utf-8") == "hello\nworld"
|