""" 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