refactor(api): enable strict typing for service API hit testing tests (#43485)

This commit is contained in:
Eddy ZHANG authored and GitHub committed 2026-10-05 00:30:13 +00:00
1 parent 70ef9cbd5d
commit e92d13220f
2 files changed
+31 -32

No files matched your search

@@ -15,7 +15,7 @@ Strategy:
""" """
import uuid import uuid
from unittest.mock import patch from unittest.mock import MagicMock, patch
import pytest import pytest
from flask import Flask, g from flask import Flask, g
@@ -74,12 +74,12 @@ def hit_testing_record() -> dict[str, object]:
class TestHitTestingPayload: class TestHitTestingPayload:
"""Test suite for HitTestingPayload Pydantic model.""" """Test suite for HitTestingPayload Pydantic model."""
def test_payload_with_required_query(self): def test_payload_with_required_query(self) -> None:
"""Test payload with required query field.""" """Test payload with required query field."""
payload = HitTestingPayload(query="test query") payload = HitTestingPayload(query="test query")
assert payload.query == "test query" assert payload.query == "test query"
def test_payload_with_all_fields(self): def test_payload_with_all_fields(self) -> None:
"""Test payload with all optional fields.""" """Test payload with all optional fields."""
retrieval_model_data = { retrieval_model_data = {
"search_method": "semantic_search", "search_method": "semantic_search",
@@ -99,17 +99,17 @@ class TestHitTestingPayload:
assert payload.external_retrieval_model == {"provider": "openai"} assert payload.external_retrieval_model == {"provider": "openai"}
assert payload.attachment_ids == ["att_1", "att_2"] assert payload.attachment_ids == ["att_1", "att_2"]
def test_payload_query_too_long(self): def test_payload_query_too_long(self) -> None:
"""Test payload rejects query over 250 characters.""" """Test payload rejects query over 250 characters."""
with pytest.raises(ValueError): with pytest.raises(ValueError):
HitTestingPayload(query="x" * 251) HitTestingPayload(query="x" * 251)
def test_payload_query_at_max_length(self): def test_payload_query_at_max_length(self) -> None:
"""Test payload accepts query at exactly 250 characters.""" """Test payload accepts query at exactly 250 characters."""
payload = HitTestingPayload(query="x" * 250) payload = HitTestingPayload(query="x" * 250)
assert len(payload.query) == 250 assert len(payload.query) == 250
def test_payload_ignores_unknown_fields_for_compatibility(self): def test_payload_ignores_unknown_fields_for_compatibility(self) -> None:
"""Top-level fields outside the documented schema remain ignored as before.""" """Top-level fields outside the documented schema remain ignored as before."""
payload = HitTestingPayload.model_validate({"query": "test query", "top_k": 3}) payload = HitTestingPayload.model_validate({"query": "test query", "top_k": 3})
@@ -146,11 +146,11 @@ class TestHitTestingApiPost:
@patch("controllers.console.datasets.hit_testing_base.DatasetService") @patch("controllers.console.datasets.hit_testing_base.DatasetService")
def test_post_success( def test_post_success(
self, self,
mock_dataset_svc, mock_dataset_svc: MagicMock,
mock_hit_svc, mock_hit_svc: MagicMock,
mock_ns, mock_ns: MagicMock,
app: Flask, app: Flask,
): ) -> None:
"""Test successful hit testing request.""" """Test successful hit testing request."""
dataset_id = str(uuid.uuid4()) dataset_id = str(uuid.uuid4())
tenant_id = str(uuid.uuid4()) tenant_id = str(uuid.uuid4())
@@ -161,7 +161,7 @@ class TestHitTestingApiPost:
mock_dataset_svc.get_dataset.return_value = mock_dataset mock_dataset_svc.get_dataset.return_value = mock_dataset
mock_dataset_svc.check_dataset_permission.return_value = None mock_dataset_svc.check_dataset_permission.return_value = None
mock_hit_svc.retrieve.return_value = {"query": {"content": "test query"}, "records": []} mock_hit_svc.retrieve.return_value = {"query": {"content": "test query"}, "records": list[object]()}
mock_hit_svc.hit_testing_args_check.return_value = None mock_hit_svc.hit_testing_args_check.return_value = None
mock_ns.payload = {"query": "test query"} mock_ns.payload = {"query": "test query"}
@@ -181,11 +181,11 @@ class TestHitTestingApiPost:
@patch("controllers.console.datasets.hit_testing_base.DatasetService") @patch("controllers.console.datasets.hit_testing_base.DatasetService")
def test_post_with_retrieval_model( def test_post_with_retrieval_model(
self, self,
mock_dataset_svc, mock_dataset_svc: MagicMock,
mock_hit_svc, mock_hit_svc: MagicMock,
mock_ns, mock_ns: MagicMock,
app: Flask, app: Flask,
): ) -> None:
"""Test hit testing with custom retrieval model.""" """Test hit testing with custom retrieval model."""
dataset_id = str(uuid.uuid4()) dataset_id = str(uuid.uuid4())
tenant_id = str(uuid.uuid4()) tenant_id = str(uuid.uuid4())
@@ -204,7 +204,7 @@ class TestHitTestingApiPost:
"score_threshold": 0.8, "score_threshold": 0.8,
} }
mock_hit_svc.retrieve.return_value = {"query": {"content": "complex query"}, "records": []} mock_hit_svc.retrieve.return_value = {"query": {"content": "complex query"}, "records": list[object]()}
mock_hit_svc.hit_testing_args_check.return_value = None mock_hit_svc.hit_testing_args_check.return_value = None
mock_ns.payload = { mock_ns.payload = {
@@ -232,11 +232,11 @@ class TestHitTestingApiPost:
@patch("controllers.console.datasets.hit_testing_base.DatasetService") @patch("controllers.console.datasets.hit_testing_base.DatasetService")
def test_post_preserves_retrieval_model_metadata_filtering_conditions( def test_post_preserves_retrieval_model_metadata_filtering_conditions(
self, self,
mock_dataset_svc, mock_dataset_svc: MagicMock,
mock_hit_svc, mock_hit_svc: MagicMock,
mock_ns, mock_ns: MagicMock,
app: Flask, app: Flask,
): ) -> None:
"""Service API retrieval payload should not drop metadata filters.""" """Service API retrieval payload should not drop metadata filters."""
dataset_id = str(uuid.uuid4()) dataset_id = str(uuid.uuid4())
tenant_id = str(uuid.uuid4()) tenant_id = str(uuid.uuid4())
@@ -246,7 +246,7 @@ class TestHitTestingApiPost:
mock_dataset_svc.get_dataset.return_value = mock_dataset mock_dataset_svc.get_dataset.return_value = mock_dataset
mock_dataset_svc.check_dataset_permission.return_value = None mock_dataset_svc.check_dataset_permission.return_value = None
mock_hit_svc.retrieve.return_value = {"query": {"content": "filtered query"}, "records": []} mock_hit_svc.retrieve.return_value = {"query": {"content": "filtered query"}, "records": list[object]()}
mock_hit_svc.hit_testing_args_check.return_value = None mock_hit_svc.hit_testing_args_check.return_value = None
metadata_filtering_conditions = { metadata_filtering_conditions = {
@@ -285,11 +285,11 @@ class TestHitTestingApiPost:
@patch("controllers.console.datasets.hit_testing_base.DatasetService") @patch("controllers.console.datasets.hit_testing_base.DatasetService")
def test_post_prepares_nullable_list_fields( def test_post_prepares_nullable_list_fields(
self, self,
mock_dataset_svc, mock_dataset_svc: MagicMock,
mock_hit_svc, mock_hit_svc: MagicMock,
mock_ns, mock_ns: MagicMock,
app: Flask, app: Flask,
): ) -> None:
"""Test service API prepares nullable list fields from retrieval records.""" """Test service API prepares nullable list fields from retrieval records."""
dataset_id = str(uuid.uuid4()) dataset_id = str(uuid.uuid4())
tenant_id = str(uuid.uuid4()) tenant_id = str(uuid.uuid4())
@@ -328,10 +328,10 @@ class TestHitTestingApiPost:
@patch("controllers.console.datasets.hit_testing_base.DatasetService") @patch("controllers.console.datasets.hit_testing_base.DatasetService")
def test_post_dataset_not_found( def test_post_dataset_not_found(
self, self,
mock_dataset_svc, mock_dataset_svc: MagicMock,
mock_ns, mock_ns: MagicMock,
app: Flask, app: Flask,
): ) -> None:
"""Test hit testing with non-existent dataset.""" """Test hit testing with non-existent dataset."""
dataset_id = str(uuid.uuid4()) dataset_id = str(uuid.uuid4())
tenant_id = str(uuid.uuid4()) tenant_id = str(uuid.uuid4())
@@ -351,10 +351,10 @@ class TestHitTestingApiPost:
@patch("controllers.console.datasets.hit_testing_base.DatasetService") @patch("controllers.console.datasets.hit_testing_base.DatasetService")
def test_post_no_dataset_permission( def test_post_no_dataset_permission(
self, self,
mock_dataset_svc, mock_dataset_svc: MagicMock,
mock_ns, mock_ns: MagicMock,
app: Flask, app: Flask,
): ) -> None:
"""Test hit testing when user lacks dataset permission.""" """Test hit testing when user lacks dataset permission."""
dataset_id = str(uuid.uuid4()) dataset_id = str(uuid.uuid4())
tenant_id = str(uuid.uuid4()) tenant_id = str(uuid.uuid4())
-1
View File
@@ -190,7 +190,6 @@ project-excludes = [
"controllers/service_api/dataset/rag_pipeline/test_rag_pipeline_workflow.py", "controllers/service_api/dataset/rag_pipeline/test_rag_pipeline_workflow.py",
"controllers/service_api/dataset/test_dataset_segment.py", "controllers/service_api/dataset/test_dataset_segment.py",
"controllers/service_api/dataset/test_document.py", "controllers/service_api/dataset/test_document.py",
"controllers/service_api/dataset/test_hit_testing.py",
"controllers/service_api/dataset/test_metadata.py", "controllers/service_api/dataset/test_metadata.py",
"controllers/service_api/dataset/test_rag_pipeline_file_upload_serialization.py", "controllers/service_api/dataset/test_rag_pipeline_file_upload_serialization.py",
"controllers/service_api/dataset/test_rag_pipeline_route_registration.py", "controllers/service_api/dataset/test_rag_pipeline_route_registration.py",