150 lines
4.9 KiB
Python
150 lines
4.9 KiB
Python
"""
|
|
Tests for field_roles update functionality.
|
|
[AC-MRS-01] 验证字段角色更新功能
|
|
"""
|
|
|
|
import pytest
|
|
import uuid
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
from app.models.entities import (
|
|
MetadataFieldDefinition,
|
|
MetadataFieldDefinitionUpdate,
|
|
MetadataFieldStatus,
|
|
)
|
|
from app.services.metadata_field_definition_service import MetadataFieldDefinitionService
|
|
|
|
|
|
class TestFieldRolesUpdate:
|
|
"""测试字段角色更新功能"""
|
|
|
|
@pytest.fixture
|
|
def mock_session(self):
|
|
"""Create mock session"""
|
|
session = MagicMock()
|
|
session.execute = AsyncMock()
|
|
session.flush = AsyncMock()
|
|
session.commit = AsyncMock()
|
|
return session
|
|
|
|
@pytest.fixture
|
|
def service(self, mock_session):
|
|
"""Create service instance"""
|
|
return MetadataFieldDefinitionService(mock_session)
|
|
|
|
@pytest.fixture
|
|
def existing_field(self):
|
|
"""Create existing field with field_roles"""
|
|
field = MagicMock(spec=MetadataFieldDefinition)
|
|
field.id = uuid.uuid4()
|
|
field.tenant_id = "test-tenant"
|
|
field.field_key = "grade"
|
|
field.label = "年级"
|
|
field.type = "string"
|
|
field.required = True
|
|
field.options = None
|
|
field.default_value = None
|
|
field.scope = ["kb_document"]
|
|
field.is_filterable = True
|
|
field.is_rank_feature = False
|
|
field.field_roles = ["slot"] # 初始角色
|
|
field.status = MetadataFieldStatus.ACTIVE.value
|
|
field.version = 1
|
|
return field
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_field_roles_success(self, service, mock_session, existing_field):
|
|
"""[AC-MRS-01] 测试成功更新字段角色"""
|
|
# Mock get_field_definition to return existing field
|
|
service.get_field_definition = AsyncMock(return_value=existing_field)
|
|
|
|
# Create update request with new field_roles
|
|
field_update = MetadataFieldDefinitionUpdate(
|
|
field_roles=["slot", "resource_filter"]
|
|
)
|
|
|
|
# Execute update
|
|
result = await service.update_field_definition(
|
|
"test-tenant",
|
|
str(existing_field.id),
|
|
field_update
|
|
)
|
|
|
|
# Verify result
|
|
assert result is not None
|
|
assert result.field_roles == ["slot", "resource_filter"]
|
|
assert result.version == 2 # Version should increment
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_field_roles_to_empty(self, service, mock_session, existing_field):
|
|
"""[AC-MRS-01] 测试将字段角色更新为空列表"""
|
|
service.get_field_definition = AsyncMock(return_value=existing_field)
|
|
|
|
field_update = MetadataFieldDefinitionUpdate(
|
|
field_roles=[]
|
|
)
|
|
|
|
result = await service.update_field_definition(
|
|
"test-tenant",
|
|
str(existing_field.id),
|
|
field_update
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.field_roles == []
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_field_roles_invalid_role(self, service, mock_session, existing_field):
|
|
"""[AC-MRS-01] 测试更新无效的字段角色"""
|
|
service.get_field_definition = AsyncMock(return_value=existing_field)
|
|
|
|
field_update = MetadataFieldDefinitionUpdate(
|
|
field_roles=["invalid_role"]
|
|
)
|
|
|
|
with pytest.raises(ValueError) as exc_info:
|
|
await service.update_field_definition(
|
|
"test-tenant",
|
|
str(existing_field.id),
|
|
field_update
|
|
)
|
|
|
|
assert "无效的字段角色" in str(exc_info.value)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_without_field_roles_unchanged(self, service, mock_session, existing_field):
|
|
"""[AC-MRS-01] 测试不更新 field_roles 时保持原值"""
|
|
service.get_field_definition = AsyncMock(return_value=existing_field)
|
|
|
|
# Update only label, not field_roles
|
|
field_update = MetadataFieldDefinitionUpdate(
|
|
label="新年级标签"
|
|
)
|
|
|
|
result = await service.update_field_definition(
|
|
"test-tenant",
|
|
str(existing_field.id),
|
|
field_update
|
|
)
|
|
|
|
assert result is not None
|
|
assert result.label == "新年级标签"
|
|
assert result.field_roles == ["slot"] # Should remain unchanged
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_field_roles_not_found(self, service, mock_session):
|
|
"""[AC-MRS-01] 测试更新不存在的字段"""
|
|
service.get_field_definition = AsyncMock(return_value=None)
|
|
|
|
field_update = MetadataFieldDefinitionUpdate(
|
|
field_roles=["slot"]
|
|
)
|
|
|
|
result = await service.update_field_definition(
|
|
"test-tenant",
|
|
str(uuid.uuid4()),
|
|
field_update
|
|
)
|
|
|
|
assert result is None
|