数据:增加测试批次模型与迁移契约

This commit is contained in:
焦龙言
2026-09-22 14:37:31 +08:00
parent 40c56c6b33
commit 17bfa2c5fe
12 changed files with 1278 additions and 32 deletions
@@ -1,4 +1,5 @@
import unittest
from datetime import datetime
from pydantic import ValidationError
from pydantic.alias_generators import to_camel
@@ -69,6 +70,21 @@ from module_business.entity.vo.report_vo import (
ShipmentReportModel,
ShipmentReportQueryModel,
)
from module_business.entity.vo.test_batch_vo import (
AdoptionExecuteRequestModel,
AdoptionPreviewRequestModel,
AdoptionRootModel,
BatchImpactModel,
PurgeExecuteRequestModel,
PurgePreviewModel,
TestBatchCreateModel,
TestBatchDetailModel,
TestBatchEditModel,
TestBatchModel,
TestBatchOptionModel,
TestBatchPreviewModel,
TestBatchUserAssignModel,
)
MASTER_MODEL_FIELDS = {
StrainModel: {
@@ -549,6 +565,71 @@ REPORT_MODEL_FIELDS = {
},
}
TEST_BATCH_MODEL_FIELDS = {
TestBatchCreateModel: {'batch_name', 'remark'},
TestBatchEditModel: {'remark'},
TestBatchUserAssignModel: {'user_ids'},
TestBatchModel: {
'batch_id',
'batch_code',
'batch_name',
'status',
'remark',
'create_by',
'create_time',
'update_by',
'update_time',
'closed_by',
'closed_at',
'purged_by',
'purged_at',
'purge_summary',
},
TestBatchOptionModel: {'batch_id', 'batch_code', 'batch_name', 'status'},
BatchImpactModel: {'table_name', 'label', 'count', 'keys'},
TestBatchDetailModel: {
'batch_id',
'batch_code',
'batch_name',
'status',
'remark',
'create_by',
'create_time',
'update_by',
'update_time',
'closed_by',
'closed_at',
'purged_by',
'purged_at',
'purge_summary',
'user_ids',
'data_summary',
},
TestBatchPreviewModel: {
'batch_id',
'batch_name',
'preview_token',
'expires_at',
'total_count',
'impacts',
},
PurgePreviewModel: {
'batch_id',
'batch_name',
'preview_token',
'expires_at',
'total_count',
'impacts',
'online_purge_allowed',
'online_purge_limit',
'blocking_reason',
},
AdoptionRootModel: {'resource_type', 'resource_ids'},
AdoptionPreviewRequestModel: {'roots'},
AdoptionExecuteRequestModel: {'roots', 'batch_name', 'preview_token'},
PurgeExecuteRequestModel: {'batch_name', 'preview_token'},
}
WRITE_MODELS = (
StrainModel,
DeleteStrainModel,
@@ -761,7 +842,7 @@ PACKAGE_MODEL_PAYLOADS = {
class BusinessVoContractTest(unittest.TestCase):
def test_all_models_have_exact_fields_and_camel_case_aliases(self) -> None:
expected_models = MASTER_MODEL_FIELDS | OPERATION_MODEL_FIELDS | REPORT_MODEL_FIELDS
expected_models = MASTER_MODEL_FIELDS | OPERATION_MODEL_FIELDS | REPORT_MODEL_FIELDS | TEST_BATCH_MODEL_FIELDS
for model_class, expected_fields in expected_models.items():
with self.subTest(model=model_class.__name__):
@@ -777,6 +858,44 @@ class BusinessVoContractTest(unittest.TestCase):
with self.subTest(model=model_class.__name__):
self.assertEqual('forbid', model_class.model_config.get('extra'))
def test_all_test_batch_models_forbid_extra_fields(self) -> None:
for model_class in TEST_BATCH_MODEL_FIELDS:
with self.subTest(model=model_class.__name__):
self.assertEqual('forbid', model_class.model_config.get('extra'))
def test_test_batch_models_accept_snake_case_and_camel_case(self) -> None:
camel_case = TestBatchCreateModel(batchName='验收批次', remark='camel')
snake_case = TestBatchCreateModel(batch_name='验收批次', remark='snake')
self.assertEqual('验收批次', camel_case.batch_name)
self.assertEqual('验收批次', snake_case.batch_name)
def test_test_batch_edit_forbids_immutable_fields(self) -> None:
for field_name, value in (('batchName', '新名称'), ('status', 'CLOSED')):
with self.subTest(field=field_name), self.assertRaises(ValidationError):
TestBatchEditModel.model_validate({'remark': None, field_name: value})
def test_test_batch_positive_ids_and_non_empty_roots_are_validated(self) -> None:
with self.assertRaises(ValidationError):
TestBatchUserAssignModel(userIds=[0])
with self.assertRaises(ValidationError):
AdoptionRootModel(resourceType='strain', resourceIds=[])
with self.assertRaises(ValidationError):
AdoptionPreviewRequestModel(roots=[])
def test_test_batch_status_rejects_unknown_value(self) -> None:
with self.assertRaises(ValidationError) as context:
TestBatchModel(
batchId=1,
batchCode='TB-1',
batchName='验收批次',
status='UNKNOWN',
createBy='admin',
createTime=datetime(2026, 9, 22),
updateBy='admin',
updateTime=datetime(2026, 9, 22),
)
self.assertIn(('status',), {tuple(error['loc']) for error in context.exception.errors()})
def test_page_queries_have_positive_defaults(self) -> None:
for model_class in PAGE_QUERY_MODELS:
with self.subTest(model=model_class.__name__):