DocHub/backend/tests/test_search_client.py
Tianyang 360e9e5a14 refactor: rename all minio references to garage, drop minio SDK for boto3
The backend no longer mentions MinIO anywhere: MinioClient -> GarageClient
(minio_client.py -> garage_client.py), MINIO_* env vars -> GARAGE_*, and
the `minio` Python package is replaced with `boto3` (AWS's generic S3
client) since Garage is the only storage backend this project targets
now. S3 API semantics are unchanged, so document_service.py's behavior
is identical — this is a naming and dependency swap, not a logic change.

Also updates test fixtures/names (FakeMinioClient -> FakeGarageClient,
FakeMinioSDK -> FakeS3SDK) and storage/README.md, which no longer frames
Garage as a MinIO replacement (that migration note has served its purpose
now that no MinIO reference remains in the codebase).

Backend: 54/54 tests passing. Frontend: 38/38 tests passing (unaffected,
verified for regressions since it talks to the backend only through the
unchanged REST API).
2026-08-01 10:51:49 +08:00

81 lines
2.6 KiB
Python

from app.search_client import SearchClient
class FakeIndex:
def __init__(self):
self.documents = {}
self.deleted_ids = []
def add_documents(self, docs):
for doc in docs:
self.documents[doc["id"]] = doc
def delete_document(self, doc_id):
self.documents.pop(doc_id, None)
self.deleted_ids.append(doc_id)
def search(self, query, params=None):
hits = []
for doc in self.documents.values():
if query in doc["content"] or query in doc["title"]:
formatted = dict(doc)
if query in doc["content"]:
formatted["content"] = doc["content"].replace(query, f"<em>{query}</em>")
hits.append({**doc, "_formatted": formatted})
return {"hits": hits}
class FakeMeilisearchSDK:
def __init__(self):
self.indexes = {}
def index(self, name):
if name not in self.indexes:
self.indexes[name] = FakeIndex()
return self.indexes[name]
def test_index_document_adds_document_with_encoded_id():
sdk = FakeMeilisearchSDK()
client = SearchClient(sdk, index_name="documents")
client.index_document(
"产品文档/架构设计.md", "产品文档", "架构设计.md", "DocHub 使用 Garage 存储文档"
)
index = sdk.indexes["documents"]
assert len(index.documents) == 1
stored = list(index.documents.values())[0]
assert stored["key"] == "产品文档/架构设计.md"
assert stored["path"] == "产品文档"
assert stored["title"] == "架构设计.md"
assert stored["content"] == "DocHub 使用 Garage 存储文档"
def test_delete_document_removes_document():
sdk = FakeMeilisearchSDK()
client = SearchClient(sdk, index_name="documents")
client.index_document("产品文档/旧文档.md", "产品文档", "旧文档.md", "旧内容")
client.delete_document("产品文档/旧文档.md")
index = sdk.indexes["documents"]
assert index.documents == {}
assert len(index.deleted_ids) == 1
def test_search_returns_matching_documents_with_highlighted_snippet():
sdk = FakeMeilisearchSDK()
client = SearchClient(sdk, index_name="documents")
client.index_document(
"产品文档/架构设计.md", "产品文档", "架构设计.md", "DocHub 支持全文检索功能"
)
results = client.search("检索")
assert len(results) == 1
assert results[0]["key"] == "产品文档/架构设计.md"
assert results[0]["title"] == "架构设计.md"
assert results[0]["path"] == "产品文档"
assert "<em>检索</em>" in results[0]["snippet"]