From 886a4479c4f8f0af05532c5b093f902fbbb81443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=84=A6=E9=BE=99=E8=A8=80?= Date: Thu, 24 Sep 2026 09:22:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E6=8B=92=E7=BB=9D?= =?UTF-8?q?=E7=BA=B3=E5=85=A5=E4=B8=8D=E5=AD=98=E5=9C=A8=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/test_batch_adoption_service.py | 14 ++++++++++++++ .../module_business/test_test_batch_adoption.py | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) 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 (