diff --git a/shierfeng-fastapi-backend/module_business/service/test_batch_adoption_service.py b/shierfeng-fastapi-backend/module_business/service/test_batch_adoption_service.py index 0a2a027..f0bf444 100644 --- a/shierfeng-fastapi-backend/module_business/service/test_batch_adoption_service.py +++ b/shierfeng-fastapi-backend/module_business/service/test_batch_adoption_service.py @@ -14,6 +14,8 @@ from module_business.domain.enums import TestBatchStatus from module_business.domain.test_batch_graph import ( BATCH_LABELS, BATCH_MODELS, + ROOT_TABLES, + BatchSelection, TestBatchGraph, issue_preview_token, selection_hash, @@ -21,6 +23,7 @@ from module_business.domain.test_batch_graph import ( from module_business.entity.vo.test_batch_vo import ( AdoptionExecuteRequestModel, AdoptionPreviewRequestModel, + AdoptionRootModel, BatchImpactModel, TestBatchPreviewModel, ) @@ -53,6 +56,16 @@ class TestBatchAdoptionService: if status != TestBatchStatus.ACTIVE.value: 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 def _assert_token(batch: object, raw_token: str, now: datetime) -> None: supplied_hash = hashlib.sha256(raw_token.encode()).hexdigest() @@ -80,6 +93,7 @@ class TestBatchAdoptionService: batch = await TestBatchDao.get_batch_for_update(db, batch_id) cls._assert_active(batch) 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: raise ServiceWarning('', '存在记录已属于其他测试批次') display_keys = await TestBatchAdoptionDao.list_display_keys(db, selection) diff --git a/shierfeng-fastapi-backend/tests/module_business/test_test_batch_adoption.py b/shierfeng-fastapi-backend/tests/module_business/test_test_batch_adoption.py index 384e981..05f5c15 100644 --- a/shierfeng-fastapi-backend/tests/module_business/test_test_batch_adoption.py +++ b/shierfeng-fastapi-backend/tests/module_business/test_test_batch_adoption.py @@ -362,6 +362,23 @@ class TestBatchAdoptionServiceTest(unittest.IsolatedAsyncioTestCase): self.db.rollback.assert_awaited_once_with() 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: lock_batch = AsyncMock() with (