数据:增加测试批次模型与迁移契约
This commit is contained in:
@@ -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__):
|
||||
|
||||
Reference in New Issue
Block a user