修复:拒绝纳入不存在的数据

This commit is contained in:
焦龙言
2026-09-24 09:22:15 +08:00
parent 02b87c9399
commit 886a4479c4
2 changed files with 31 additions and 0 deletions
@@ -14,6 +14,8 @@ from module_business.domain.enums import TestBatchStatus
from module_business.domain.test_batch_graph import ( from module_business.domain.test_batch_graph import (
BATCH_LABELS, BATCH_LABELS,
BATCH_MODELS, BATCH_MODELS,
ROOT_TABLES,
BatchSelection,
TestBatchGraph, TestBatchGraph,
issue_preview_token, issue_preview_token,
selection_hash, selection_hash,
@@ -21,6 +23,7 @@ from module_business.domain.test_batch_graph import (
from module_business.entity.vo.test_batch_vo import ( from module_business.entity.vo.test_batch_vo import (
AdoptionExecuteRequestModel, AdoptionExecuteRequestModel,
AdoptionPreviewRequestModel, AdoptionPreviewRequestModel,
AdoptionRootModel,
BatchImpactModel, BatchImpactModel,
TestBatchPreviewModel, TestBatchPreviewModel,
) )
@@ -53,6 +56,16 @@ class TestBatchAdoptionService:
if status != TestBatchStatus.ACTIVE.value: if status != TestBatchStatus.ACTIVE.value:
raise ServiceWarning('', '测试批次状态异常') raise ServiceWarning('', '测试批次状态异常')
@staticmethod
def _assert_roots_exist(
roots: list[AdoptionRootModel],
selection: BatchSelection,
) -> None:
for root in roots:
table_name = ROOT_TABLES[root.resource_type]
if not set(root.resource_ids).issubset(selection[table_name]):
raise ServiceWarning('', '指定的旧数据不存在')
@staticmethod @staticmethod
def _assert_token(batch: object, raw_token: str, now: datetime) -> None: def _assert_token(batch: object, raw_token: str, now: datetime) -> None:
supplied_hash = hashlib.sha256(raw_token.encode()).hexdigest() supplied_hash = hashlib.sha256(raw_token.encode()).hexdigest()
@@ -80,6 +93,7 @@ class TestBatchAdoptionService:
batch = await TestBatchDao.get_batch_for_update(db, batch_id) batch = await TestBatchDao.get_batch_for_update(db, batch_id)
cls._assert_active(batch) cls._assert_active(batch)
selection = await TestBatchGraph.compute_closure(db, command.roots) selection = await TestBatchGraph.compute_closure(db, command.roots)
cls._assert_roots_exist(command.roots, selection)
if await TestBatchAdoptionDao.find_tagged_record(db, selection) is not None: if await TestBatchAdoptionDao.find_tagged_record(db, selection) is not None:
raise ServiceWarning('', '存在记录已属于其他测试批次') raise ServiceWarning('', '存在记录已属于其他测试批次')
display_keys = await TestBatchAdoptionDao.list_display_keys(db, selection) display_keys = await TestBatchAdoptionDao.list_display_keys(db, selection)
@@ -362,6 +362,23 @@ class TestBatchAdoptionServiceTest(unittest.IsolatedAsyncioTestCase):
self.db.rollback.assert_awaited_once_with() self.db.rollback.assert_awaited_once_with()
self.db.commit.assert_not_awaited() self.db.commit.assert_not_awaited()
async def test_preview_rejects_when_any_requested_root_does_not_exist(self) -> None:
batch = make_batch()
command = AdoptionPreviewRequestModel(roots=[AdoptionRootModel(resourceType='pallet', resourceIds=[10, 999])])
with (
self._preview_stack(batch),
self.assertRaisesRegex(ServiceWarning, '指定的旧数据不存在'),
):
await TestBatchAdoptionService.preview(self.db, 7, command, make_admin())
self.assertIsNone(batch.preview_action)
self.assertIsNone(batch.preview_token_hash)
self.assertIsNone(batch.preview_scope_hash)
self.assertIsNone(batch.preview_expires_at)
self.db.rollback.assert_awaited_once_with()
self.db.commit.assert_not_awaited()
async def test_regular_user_is_rejected_before_locking_batch(self) -> None: async def test_regular_user_is_rejected_before_locking_batch(self) -> None:
lock_batch = AsyncMock() lock_batch = AsyncMock()
with ( with (