mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-02 13:57:30 +08:00
Refactor: migrate doc upload info used in chat (#14359)
### What problem does this PR solve? Before migration: POST /v1/document/upload_info/ After migration: POST /api/v1/documentss/upload/ ### Type of change - [x] Refactoring
This commit is contained in:
@@ -15,12 +15,12 @@
|
||||
#
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
import importlib.util
|
||||
import sys
|
||||
from types import ModuleType
|
||||
|
||||
import pytest
|
||||
from test_common import upload_info
|
||||
from configs import INVALID_API_TOKEN
|
||||
from libs.auth import RAGFlowWebApiAuth
|
||||
from utils.file_utils import create_txt_file
|
||||
|
||||
|
||||
class _AwaitableValue:
|
||||
@@ -61,81 +61,55 @@ def _run(coro):
|
||||
return asyncio.run(coro)
|
||||
|
||||
|
||||
def _load_document_app_module(monkeypatch):
|
||||
repo_root = Path(__file__).resolve().parents[4]
|
||||
common_mod = ModuleType("common")
|
||||
common_mod.bulk_upload_documents = lambda *_args, **_kwargs: []
|
||||
common_mod.delete_document = lambda *_args, **_kwargs: None
|
||||
common_mod.list_documents = lambda *_args, **_kwargs: {"data": {"docs": []}}
|
||||
monkeypatch.setitem(sys.modules, "common", common_mod)
|
||||
module_path = repo_root / "test" / "testcases" / "test_web_api" / "test_document_app" / "conftest.py"
|
||||
spec = importlib.util.spec_from_file_location("test_document_app_unit_conftest", module_path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules["test_document_app_unit_conftest"] = module
|
||||
spec.loader.exec_module(module)
|
||||
return module.document_app_module.__wrapped__(monkeypatch)
|
||||
|
||||
# ============================================================================
|
||||
# End-to-End Tests
|
||||
# ============================================================================
|
||||
|
||||
@pytest.mark.p2
|
||||
def test_upload_info_rejects_mixed_inputs(monkeypatch):
|
||||
module = _load_document_app_module(monkeypatch)
|
||||
monkeypatch.setattr(module, "assert_url_is_safe", lambda url: ("example.com", "93.184.216.34"))
|
||||
files = _DummyFiles({"file": [_DummyFile("a.txt")]})
|
||||
monkeypatch.setattr(module, "request", _DummyRequest(files=files, args={"url": "https://example.com/a.txt"}))
|
||||
class TestUploadInfoE2E:
|
||||
"""End-to-end tests for the /api/v1/documents/upload endpoint"""
|
||||
|
||||
res = _run(module.upload_info())
|
||||
assert res["code"] == module.RetCode.BAD_REQUEST
|
||||
assert "not both" in res["message"]
|
||||
def test_upload_info_requires_file_or_url_e2e(self, WebApiAuth):
|
||||
"""Test that missing both file and url returns error"""
|
||||
# Call without files and without url
|
||||
res = upload_info(WebApiAuth)
|
||||
assert res["code"] == 101, res
|
||||
assert "Missing input" in res["message"] or "file" in res["message"].lower() or "url" in res["message"].lower()
|
||||
|
||||
def test_upload_info_rejects_mixed_inputs_e2e(self, WebApiAuth, tmp_path):
|
||||
"""Test that providing both file and url returns error"""
|
||||
# Create a file
|
||||
fp = create_txt_file(tmp_path / "test.txt")
|
||||
|
||||
@pytest.mark.p2
|
||||
def test_upload_info_requires_file_or_url(monkeypatch):
|
||||
module = _load_document_app_module(monkeypatch)
|
||||
monkeypatch.setattr(module, "request", _DummyRequest(files=_DummyFiles()))
|
||||
# Call with both file and url - the API should reject this
|
||||
res = upload_info(WebApiAuth, files_path=[fp], url="https://example.com/test.txt")
|
||||
# The API should return an error when both file and url are provided
|
||||
assert res["code"] == 101, res
|
||||
assert "not both" in res["message"].lower() and "either" in res["message"].lower()
|
||||
|
||||
res = _run(module.upload_info())
|
||||
assert res["code"] == module.RetCode.BAD_REQUEST
|
||||
assert "Missing input" in res["message"]
|
||||
def test_upload_info_supports_url_single_and_multiple_files_e2e(self, WebApiAuth, tmp_path):
|
||||
"""Test that the endpoint supports URL, single file, and multiple files"""
|
||||
# Test with URL
|
||||
# Note: Using a real URL might fail if the URL is not accessible
|
||||
# For E2E testing, we test with actual file uploads
|
||||
|
||||
# Test with single file
|
||||
fp1 = create_txt_file(tmp_path / "single_file.txt")
|
||||
res = upload_info(WebApiAuth, files_path=[fp1])
|
||||
assert res["code"] == 0, res
|
||||
assert "data" in res, res
|
||||
|
||||
@pytest.mark.p2
|
||||
def test_upload_info_supports_url_single_and_multiple_files(monkeypatch):
|
||||
module = _load_document_app_module(monkeypatch)
|
||||
monkeypatch.setattr(module, "assert_url_is_safe", lambda url: ("example.com", "93.184.216.34"))
|
||||
captured = []
|
||||
# Test with multiple files
|
||||
fp2 = create_txt_file(tmp_path / "file_a.txt")
|
||||
fp3 = create_txt_file(tmp_path / "file_b.txt")
|
||||
res = upload_info(WebApiAuth, files_path=[fp2, fp3])
|
||||
assert res["code"] == 0, res
|
||||
assert "data" in res, res
|
||||
# Should return a list for multiple files
|
||||
if isinstance(res["data"], list):
|
||||
assert len(res["data"]) == 2, res
|
||||
|
||||
def fake_upload_info(user_id, file_obj, url=None):
|
||||
captured.append((user_id, getattr(file_obj, "filename", None), url))
|
||||
if url is not None:
|
||||
return {"kind": "url", "value": url}
|
||||
return {"kind": "file", "value": file_obj.filename}
|
||||
|
||||
monkeypatch.setattr(module.FileService, "upload_info", fake_upload_info)
|
||||
|
||||
monkeypatch.setattr(module, "request", _DummyRequest(files=_DummyFiles(), args={"url": "https://example.com/a.txt"}))
|
||||
res = _run(module.upload_info())
|
||||
assert res["code"] == 0
|
||||
assert res["data"] == {"kind": "url", "value": "https://example.com/a.txt"}
|
||||
|
||||
monkeypatch.setattr(module, "request", _DummyRequest(files=_DummyFiles({"file": _DummyFile("single.txt")})))
|
||||
res = _run(module.upload_info())
|
||||
assert res["code"] == 0
|
||||
assert res["data"] == {"kind": "file", "value": "single.txt"}
|
||||
|
||||
monkeypatch.setattr(
|
||||
module,
|
||||
"request",
|
||||
_DummyRequest(files=_DummyFiles({"file": [_DummyFile("a.txt"), _DummyFile("b.txt")]})),
|
||||
)
|
||||
res = _run(module.upload_info())
|
||||
assert res["code"] == 0
|
||||
assert res["data"] == [
|
||||
{"kind": "file", "value": "a.txt"},
|
||||
{"kind": "file", "value": "b.txt"},
|
||||
]
|
||||
assert captured == [
|
||||
("user-1", None, "https://example.com/a.txt"),
|
||||
("user-1", "single.txt", None),
|
||||
("user-1", "a.txt", None),
|
||||
("user-1", "b.txt", None),
|
||||
]
|
||||
def test_upload_info_invalid_auth(self):
|
||||
"""Test that invalid authentication returns error"""
|
||||
res = upload_info(RAGFlowWebApiAuth(INVALID_API_TOKEN), files_path=[])
|
||||
assert res["code"] == 401, res
|
||||
|
||||
Reference in New Issue
Block a user