test_upload.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. """Public attachment upload (local storage)."""
  2. import pytest
  3. from app.core.config import get_settings
  4. @pytest.fixture
  5. def local_storage_env(tmp_path, monkeypatch):
  6. monkeypatch.setenv("STORAGE_TYPE", "local")
  7. monkeypatch.setenv("LOCAL_STORAGE_DIR", str(tmp_path))
  8. get_settings.cache_clear()
  9. yield tmp_path
  10. get_settings.cache_clear()
  11. def test_public_upload(client, local_storage_env):
  12. files = {"file": ("a.png", b"fake-png-bytes", "image/png")}
  13. r = client.post("/api/public/attachment/upload", files=files)
  14. assert r.status_code == 200
  15. data = r.json()["data"]
  16. assert data["url"]
  17. assert data["id"]
  18. assert data["fileName"] == "a.png"
  19. assert data["size"] == len(b"fake-png-bytes")
  20. assert data["url"].startswith("/uploads/")
  21. def test_public_upload_rejects_path_traversal(client, local_storage_env):
  22. base = local_storage_env
  23. outside = (base / ".." / "outside").resolve()
  24. assert not outside.exists()
  25. files = {"file": ("evil.png", b"evil-bytes", "image/png")}
  26. r = client.post(
  27. "/api/public/attachment/upload",
  28. files=files,
  29. data={"folder": "../outside"},
  30. )
  31. assert r.status_code == 400
  32. body = r.json()
  33. assert body["code"] == 400
  34. assert "message" in body
  35. assert "detail" not in body
  36. assert not outside.exists()
  37. assert not any(base.rglob("*"))