diff --git a/src/test/java/com/ycwl/basic/face/pipeline/integration/FaceMatchingPipelineIntegrationTest.java b/src/test/java/com/ycwl/basic/face/pipeline/integration/FaceMatchingPipelineIntegrationTest.java index e73e9c08..146c27a1 100644 --- a/src/test/java/com/ycwl/basic/face/pipeline/integration/FaceMatchingPipelineIntegrationTest.java +++ b/src/test/java/com/ycwl/basic/face/pipeline/integration/FaceMatchingPipelineIntegrationTest.java @@ -1,13 +1,35 @@ package com.ycwl.basic.face.pipeline.integration; import com.ycwl.basic.face.pipeline.core.FaceMatchingContext; -import com.ycwl.basic.pipeline.core.Pipeline; import com.ycwl.basic.face.pipeline.enums.FaceMatchingScene; import com.ycwl.basic.face.pipeline.factory.FaceMatchingPipelineFactory; +import com.ycwl.basic.face.pipeline.stages.BuildSourceRelationStage; +import com.ycwl.basic.face.pipeline.stages.CreateTaskStage; +import com.ycwl.basic.face.pipeline.stages.CustomFaceSearchStage; +import com.ycwl.basic.face.pipeline.stages.DeleteOldRelationsStage; +import com.ycwl.basic.face.pipeline.stages.FaceRecognitionStage; +import com.ycwl.basic.face.pipeline.stages.FaceRecoveryStage; +import com.ycwl.basic.face.pipeline.stages.FilterByDevicePhotoLimitStage; +import com.ycwl.basic.face.pipeline.stages.FilterByTimeRangeStage; +import com.ycwl.basic.face.pipeline.stages.GeneratePuzzleStage; +import com.ycwl.basic.face.pipeline.stages.HandleVideoRecreationStage; +import com.ycwl.basic.face.pipeline.stages.LoadFaceSamplesStage; +import com.ycwl.basic.face.pipeline.stages.LoadMatchedSamplesStage; +import com.ycwl.basic.face.pipeline.stages.PersistRelationsStage; +import com.ycwl.basic.face.pipeline.stages.PrepareContextStage; +import com.ycwl.basic.face.pipeline.stages.ProcessBuyStatusStage; +import com.ycwl.basic.face.pipeline.stages.ProcessFreeSourceStage; +import com.ycwl.basic.face.pipeline.stages.RecordCustomMatchMetricsStage; +import com.ycwl.basic.face.pipeline.stages.RecordMetricsStage; +import com.ycwl.basic.face.pipeline.stages.SetTaskStatusStage; +import com.ycwl.basic.face.pipeline.stages.UpdateFaceResultStage; +import com.ycwl.basic.pipeline.core.Pipeline; +import com.ycwl.basic.service.pc.helper.ScenicConfigFacade; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.Arrays; @@ -17,13 +39,55 @@ import static org.junit.jupiter.api.Assertions.*; * Pipeline集成测试 * 测试Pipeline的完整流程和Stage协作 */ -@SpringBootTest -@ActiveProfiles("test") +@ExtendWith(MockitoExtension.class) class FaceMatchingPipelineIntegrationTest { - @Autowired + @InjectMocks private FaceMatchingPipelineFactory pipelineFactory; + @Mock + private PrepareContextStage prepareContextStage; + @Mock + private RecordMetricsStage recordMetricsStage; + @Mock + private FaceRecognitionStage faceRecognitionStage; + @Mock + private FaceRecoveryStage faceRecoveryStage; + @Mock + private UpdateFaceResultStage updateFaceResultStage; + @Mock + private BuildSourceRelationStage buildSourceRelationStage; + @Mock + private ProcessFreeSourceStage processFreeSourceStage; + @Mock + private ProcessBuyStatusStage processBuyStatusStage; + @Mock + private HandleVideoRecreationStage handleVideoRecreationStage; + @Mock + private PersistRelationsStage persistRelationsStage; + @Mock + private CreateTaskStage createTaskStage; + @Mock + private SetTaskStatusStage setTaskStatusStage; + @Mock + private GeneratePuzzleStage generatePuzzleStage; + @Mock + private RecordCustomMatchMetricsStage recordCustomMatchMetricsStage; + @Mock + private LoadFaceSamplesStage loadFaceSamplesStage; + @Mock + private CustomFaceSearchStage customFaceSearchStage; + @Mock + private LoadMatchedSamplesStage loadMatchedSamplesStage; + @Mock + private FilterByTimeRangeStage filterByTimeRangeStage; + @Mock + private FilterByDevicePhotoLimitStage filterByDevicePhotoLimitStage; + @Mock + private DeleteOldRelationsStage deleteOldRelationsStage; + @Mock + private ScenicConfigFacade scenicConfigFacade; + /** * 测试Pipeline工厂能够成功创建Pipeline */ @@ -43,7 +107,7 @@ class FaceMatchingPipelineIntegrationTest { // 验证Stage数量符合预期 assertEquals(13, autoMatchingNew.getStageCount()); - assertEquals(13, autoMatchingOld.getStageCount()); + assertEquals(12, autoMatchingOld.getStageCount()); assertEquals(15, customMatching.getStageCount()); assertEquals(3, recognitionOnly.getStageCount()); } diff --git a/src/test/java/com/ycwl/basic/face/pipeline/stages/CreateTaskStageTest.java b/src/test/java/com/ycwl/basic/face/pipeline/stages/CreateTaskStageTest.java index 3bebab8e..2473f3ba 100644 --- a/src/test/java/com/ycwl/basic/face/pipeline/stages/CreateTaskStageTest.java +++ b/src/test/java/com/ycwl/basic/face/pipeline/stages/CreateTaskStageTest.java @@ -1,5 +1,7 @@ package com.ycwl.basic.face.pipeline.stages; +import com.ycwl.basic.biz.FaceStatusManager; +import com.ycwl.basic.enums.FaceCutStatus; import com.ycwl.basic.face.pipeline.core.FaceMatchingContext; import com.ycwl.basic.pipeline.core.StageResult; import com.ycwl.basic.model.pc.face.entity.FaceEntity; @@ -27,6 +29,9 @@ class CreateTaskStageTest { @Mock private TaskService taskService; + @Mock + private FaceStatusManager faceStatusManager; + @InjectMocks private CreateTaskStage stage; @@ -60,7 +65,7 @@ class CreateTaskStageTest { assertTrue(result.getMessage().contains("自动创建任务成功")); verify(scenicConfigFacade, times(1)).isFaceSelectFirst(10L); verify(taskService, times(1)).autoCreateTaskByFaceId(1L); -// verify(taskStatusBiz, never()).setFaceCutStatus(anyLong(), anyInt()); + verify(faceStatusManager, never()).setFaceCutStatus(anyLong(), any(FaceCutStatus.class)); } @Test @@ -76,7 +81,7 @@ class CreateTaskStageTest { assertTrue(result.isSkipped()); assertTrue(result.getMessage().contains("等待用户手动选择")); verify(scenicConfigFacade, times(1)).isFaceSelectFirst(10L); -// verify(taskStatusBiz, times(1)).setFaceCutStatus(1L, 2); + verify(faceStatusManager, times(1)).setFaceCutStatus(1L, FaceCutStatus.WAITING_USER_SELECT); verify(taskService, never()).autoCreateTaskByFaceId(anyLong()); } @@ -94,7 +99,7 @@ class CreateTaskStageTest { assertTrue(result.getMessage().contains("任务创建失败")); verify(scenicConfigFacade, times(1)).isFaceSelectFirst(10L); verify(taskService, never()).autoCreateTaskByFaceId(anyLong()); -// verify(taskStatusBiz, never()).setFaceCutStatus(anyLong(), anyInt()); + verify(faceStatusManager, never()).setFaceCutStatus(anyLong(), any(FaceCutStatus.class)); } @Test @@ -119,8 +124,8 @@ class CreateTaskStageTest { // Given: 设置状态失败 when(scenicConfigFacade.isFaceSelectFirst(10L)) .thenReturn(true); -// doThrow(new RuntimeException("Status set error")) -// .when(taskStatusBiz).setFaceCutStatus(1L, 2); + doThrow(new RuntimeException("Status set error")) + .when(faceStatusManager).setFaceCutStatus(1L, FaceCutStatus.WAITING_USER_SELECT); // When StageResult result = stage.execute(context); @@ -128,7 +133,7 @@ class CreateTaskStageTest { // Then assertTrue(result.isDegraded()); assertTrue(result.getMessage().contains("任务创建失败")); -// verify(taskStatusBiz, times(1)).setFaceCutStatus(1L, 2); + verify(faceStatusManager, times(1)).setFaceCutStatus(1L, FaceCutStatus.WAITING_USER_SELECT); } @Test diff --git a/src/test/java/com/ycwl/basic/face/pipeline/stages/DeleteOldRelationsStageTest.java b/src/test/java/com/ycwl/basic/face/pipeline/stages/DeleteOldRelationsStageTest.java index 8cabf77e..28c95b0c 100644 --- a/src/test/java/com/ycwl/basic/face/pipeline/stages/DeleteOldRelationsStageTest.java +++ b/src/test/java/com/ycwl/basic/face/pipeline/stages/DeleteOldRelationsStageTest.java @@ -1,5 +1,6 @@ package com.ycwl.basic.face.pipeline.stages; +import com.ycwl.basic.biz.FaceStatusManager; import com.ycwl.basic.face.pipeline.core.FaceMatchingContext; import com.ycwl.basic.pipeline.core.StageResult; import com.ycwl.basic.mapper.SourceMapper; @@ -32,6 +33,9 @@ class DeleteOldRelationsStageTest { @Mock private MemberRelationRepository memberRelationRepository; + @Mock + private FaceStatusManager faceStatusManager; + @InjectMocks private DeleteOldRelationsStage stage; @@ -63,6 +67,7 @@ class DeleteOldRelationsStageTest { verify(sourceMapper, times(1)).deleteNotBuyFaceRelation(100L, 1L); verify(videoMapper, times(1)).deleteNotBuyFaceRelations(100L, 1L); verify(memberRelationRepository, times(1)).clearSCacheByFace(1L); + verify(faceStatusManager, times(1)).invalidatePuzzleSourceVersion(1L); } @Test @@ -80,6 +85,7 @@ class DeleteOldRelationsStageTest { verify(sourceMapper, times(1)).deleteNotBuyFaceRelation(100L, 1L); verify(videoMapper, never()).deleteNotBuyFaceRelations(anyLong(), anyLong()); verify(memberRelationRepository, never()).clearSCacheByFace(anyLong()); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -96,6 +102,7 @@ class DeleteOldRelationsStageTest { verify(sourceMapper, times(1)).deleteNotBuyFaceRelation(100L, 1L); verify(videoMapper, times(1)).deleteNotBuyFaceRelations(100L, 1L); verify(memberRelationRepository, never()).clearSCacheByFace(anyLong()); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -110,6 +117,7 @@ class DeleteOldRelationsStageTest { // Then assertTrue(result.isDegraded()); verify(memberRelationRepository, times(1)).clearSCacheByFace(1L); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -124,6 +132,7 @@ class DeleteOldRelationsStageTest { assertTrue(result.isSuccess()); verify(sourceMapper, times(1)).deleteNotBuyFaceRelation(999L, 1L); verify(videoMapper, times(1)).deleteNotBuyFaceRelations(999L, 1L); + verify(faceStatusManager, times(1)).invalidatePuzzleSourceVersion(1L); } @Test @@ -141,6 +150,7 @@ class DeleteOldRelationsStageTest { verify(sourceMapper, times(1)).deleteNotBuyFaceRelation(100L, 888L); verify(videoMapper, times(1)).deleteNotBuyFaceRelations(100L, 888L); verify(memberRelationRepository, times(1)).clearSCacheByFace(888L); + verify(faceStatusManager, times(1)).invalidatePuzzleSourceVersion(888L); } @Test @@ -155,6 +165,7 @@ class DeleteOldRelationsStageTest { // Then assertTrue(result.isDegraded()); assertTrue(result.getMessage().contains("删除旧关系数据失败")); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -171,5 +182,6 @@ class DeleteOldRelationsStageTest { // source删除成功,但video删除失败 verify(sourceMapper, times(1)).deleteNotBuyFaceRelation(100L, 1L); verify(videoMapper, times(1)).deleteNotBuyFaceRelations(100L, 1L); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } } diff --git a/src/test/java/com/ycwl/basic/face/pipeline/stages/PersistRelationsStageTest.java b/src/test/java/com/ycwl/basic/face/pipeline/stages/PersistRelationsStageTest.java index 427a04ef..5e88a12b 100644 --- a/src/test/java/com/ycwl/basic/face/pipeline/stages/PersistRelationsStageTest.java +++ b/src/test/java/com/ycwl/basic/face/pipeline/stages/PersistRelationsStageTest.java @@ -1,5 +1,6 @@ package com.ycwl.basic.face.pipeline.stages; +import com.ycwl.basic.biz.FaceStatusManager; import com.ycwl.basic.face.pipeline.core.FaceMatchingContext; import com.ycwl.basic.pipeline.core.StageResult; import com.ycwl.basic.mapper.SourceMapper; @@ -33,6 +34,9 @@ class PersistRelationsStageTest { @Mock private MemberRelationRepository memberRelationRepository; + @Mock + private FaceStatusManager faceStatusManager; + @InjectMocks private PersistRelationsStage stage; @@ -67,6 +71,7 @@ class PersistRelationsStageTest { verify(sourceMapper, times(1)).filterValidSourceRelations(afterExistingFilter); verify(sourceMapper, times(1)).addRelations(afterValidFilter); verify(memberRelationRepository, times(1)).clearSCacheByFace(1L); + verify(faceStatusManager, times(1)).invalidatePuzzleSourceVersion(1L); } @Test @@ -82,6 +87,7 @@ class PersistRelationsStageTest { assertTrue(result.getMessage().contains("memberSourceList为空")); verify(sourceMapper, never()).filterExistingRelations(anyList()); verify(sourceMapper, never()).addRelations(anyList()); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -96,6 +102,7 @@ class PersistRelationsStageTest { assertTrue(result.isSkipped()); assertTrue(result.getMessage().contains("memberSourceList为空")); verify(sourceMapper, never()).filterExistingRelations(anyList()); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -116,6 +123,7 @@ class PersistRelationsStageTest { verify(sourceMapper, times(1)).filterExistingRelations(memberSourceList); verify(sourceMapper, never()).addRelations(anyList()); verify(memberRelationRepository, never()).clearSCacheByFace(anyLong()); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -139,6 +147,7 @@ class PersistRelationsStageTest { assertTrue(result.getMessage().contains("没有有效的关联关系可创建")); verify(sourceMapper, times(1)).filterValidSourceRelations(afterExistingFilter); verify(sourceMapper, never()).addRelations(anyList()); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -162,6 +171,7 @@ class PersistRelationsStageTest { assertTrue(result.isSuccess()); assertTrue(result.getMessage().contains("持久化了5条关联关系")); verify(sourceMapper, times(1)).addRelations(afterValidFilter); + verify(faceStatusManager, times(1)).invalidatePuzzleSourceVersion(1L); } @Test @@ -181,6 +191,7 @@ class PersistRelationsStageTest { assertTrue(result.getMessage().contains("保存关联关系失败")); assertNotNull(result.getException()); verify(sourceMapper, never()).addRelations(anyList()); + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -204,6 +215,7 @@ class PersistRelationsStageTest { // Then assertTrue(result.isFailed()); verify(memberRelationRepository, never()).clearSCacheByFace(anyLong()); // 失败时不清缓存 + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -228,6 +240,7 @@ class PersistRelationsStageTest { // Then assertTrue(result.isFailed()); // 缓存清理失败导致整体失败 verify(sourceMapper, times(1)).addRelations(afterValidFilter); // 但关系已保存 + verify(faceStatusManager, never()).invalidatePuzzleSourceVersion(anyLong()); } @Test @@ -247,6 +260,7 @@ class PersistRelationsStageTest { // Then assertTrue(result.isSuccess()); assertTrue(result.getMessage().contains("持久化了1条关联关系")); + verify(faceStatusManager, times(1)).invalidatePuzzleSourceVersion(1L); } private List createMemberSourceList(int count) { diff --git a/src/test/java/com/ycwl/basic/face/pipeline/stages/SetTaskStatusStageTest.java b/src/test/java/com/ycwl/basic/face/pipeline/stages/SetTaskStatusStageTest.java index e30ec14a..2e5839b9 100644 --- a/src/test/java/com/ycwl/basic/face/pipeline/stages/SetTaskStatusStageTest.java +++ b/src/test/java/com/ycwl/basic/face/pipeline/stages/SetTaskStatusStageTest.java @@ -1,16 +1,21 @@ package com.ycwl.basic.face.pipeline.stages; +import com.ycwl.basic.biz.FaceStatusManager; +import com.ycwl.basic.enums.FaceCutStatus; import com.ycwl.basic.face.pipeline.core.FaceMatchingContext; import com.ycwl.basic.pipeline.core.StageResult; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; +import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.util.Arrays; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.*; /** * SetTaskStatusStage 单元测试 @@ -21,6 +26,9 @@ class SetTaskStatusStageTest { @InjectMocks private SetTaskStatusStage stage; + @Mock + private FaceStatusManager faceStatusManager; + private FaceMatchingContext context; @BeforeEach @@ -41,7 +49,7 @@ class SetTaskStatusStageTest { // Then assertTrue(result.isSuccess()); assertTrue(result.getMessage().contains("任务状态已设置")); -// verify(taskStatusBiz, times(1)).setFaceCutStatus(1L, 0); + verify(faceStatusManager, times(1)).setFaceCutStatus(1L, FaceCutStatus.CUTTING); } @Test @@ -55,7 +63,7 @@ class SetTaskStatusStageTest { // Then assertTrue(result.isSkipped()); assertTrue(result.getMessage().contains("非新用户")); -// verify(taskStatusBiz, never()).setFaceCutStatus(anyLong(), anyInt()); + verify(faceStatusManager, never()).setFaceCutStatus(anyLong(), any(FaceCutStatus.class)); } @Test @@ -63,8 +71,8 @@ class SetTaskStatusStageTest { // Given context = FaceMatchingContext.forAutoMatching(1L, true); -// doThrow(new RuntimeException("Database error")) -// .when(taskStatusBiz).setFaceCutStatus(1L, 0); + doThrow(new RuntimeException("Database error")) + .when(faceStatusManager).setFaceCutStatus(1L, FaceCutStatus.CUTTING); // When StageResult result = stage.execute(context); @@ -72,7 +80,7 @@ class SetTaskStatusStageTest { // Then assertTrue(result.isDegraded()); // 降级处理,不影响主流程 assertTrue(result.getMessage().contains("任务状态设置失败")); -// verify(taskStatusBiz, times(1)).setFaceCutStatus(1L, 0); + verify(faceStatusManager, times(1)).setFaceCutStatus(1L, FaceCutStatus.CUTTING); } @Test @@ -87,7 +95,7 @@ class SetTaskStatusStageTest { // Then assertTrue(result.isSuccess()); -// verify(taskStatusBiz, times(1)).setFaceCutStatus(999L, 0); + verify(faceStatusManager, times(1)).setFaceCutStatus(999L, FaceCutStatus.CUTTING); } @Test @@ -100,7 +108,7 @@ class SetTaskStatusStageTest { // Then assertTrue(result.isSkipped()); -// verify(taskStatusBiz, never()).setFaceCutStatus(anyLong(), anyInt()); + verify(faceStatusManager, never()).setFaceCutStatus(anyLong(), any(FaceCutStatus.class)); } @Test @@ -114,7 +122,7 @@ class SetTaskStatusStageTest { // Then assertTrue(result.isSkipped()); -// verify(taskStatusBiz, never()).setFaceCutStatus(anyLong(), anyInt()); + verify(faceStatusManager, never()).setFaceCutStatus(anyLong(), any(FaceCutStatus.class)); } @Test @@ -122,8 +130,8 @@ class SetTaskStatusStageTest { // Given context = FaceMatchingContext.forAutoMatching(1L, true); -// doThrow(new NullPointerException("Null task status")) -// .when(taskStatusBiz).setFaceCutStatus(1L, 0); + doThrow(new NullPointerException("Null task status")) + .when(faceStatusManager).setFaceCutStatus(1L, FaceCutStatus.CUTTING); // When StageResult result = stage.execute(context); @@ -131,6 +139,7 @@ class SetTaskStatusStageTest { // Then assertTrue(result.isDegraded()); assertTrue(result.getMessage().contains("任务状态设置失败")); + verify(faceStatusManager, times(1)).setFaceCutStatus(1L, FaceCutStatus.CUTTING); } @Test @@ -143,6 +152,7 @@ class SetTaskStatusStageTest { // Then assertFalse(result.isSkipped()); // 应该执行 + verify(faceStatusManager, times(1)).setFaceCutStatus(1L, FaceCutStatus.CUTTING); } @Test @@ -155,5 +165,6 @@ class SetTaskStatusStageTest { // Then assertTrue(result.isSkipped()); // 应该跳过 + verify(faceStatusManager, never()).setFaceCutStatus(anyLong(), any(FaceCutStatus.class)); } } diff --git a/src/test/java/com/ycwl/basic/image/pipeline/core/PipelineBuilderTest.java b/src/test/java/com/ycwl/basic/image/pipeline/core/PipelineBuilderTest.java index 5ea56ae3..36845efa 100644 --- a/src/test/java/com/ycwl/basic/image/pipeline/core/PipelineBuilderTest.java +++ b/src/test/java/com/ycwl/basic/image/pipeline/core/PipelineBuilderTest.java @@ -19,7 +19,7 @@ class PipelineBuilderTest { Exception exception = assertThrows(IllegalStateException.class, builder::build); - assertEquals("管线至少需要一个Stage", exception.getMessage()); + assertEquals("Pipeline 至少需要一个 Stage", exception.getMessage()); } @Test diff --git a/src/test/java/com/ycwl/basic/image/pipeline/stages/ImageEnhanceStageTest.java b/src/test/java/com/ycwl/basic/image/pipeline/stages/ImageEnhanceStageTest.java index 78f29f1e..37f89218 100644 --- a/src/test/java/com/ycwl/basic/image/pipeline/stages/ImageEnhanceStageTest.java +++ b/src/test/java/com/ycwl/basic/image/pipeline/stages/ImageEnhanceStageTest.java @@ -146,8 +146,13 @@ class ImageEnhanceStageTest { } @Test - void testExecute_NoCurrentFile_ShouldFail() { - ImageEnhanceStage stage = new ImageEnhanceStage(); + void testExecute_NoCurrentFile_ShouldSkip() { + BceEnhancerConfig validConfig = new BceEnhancerConfig(); + validConfig.setAppId("valid-app-id"); + validConfig.setApiKey("valid-api-key"); + validConfig.setSecretKey("valid-secret-key"); + + ImageEnhanceStage stage = new ImageEnhanceStage(validConfig); PhotoProcessContext context = PhotoProcessContext.builder() .originalUrl("https://example.com/test.jpg") @@ -157,7 +162,7 @@ class ImageEnhanceStageTest { StageResult result = stage.execute(context); - assertTrue(result.isFailed()); + assertTrue(result.isSkipped()); assertEquals("当前文件不存在", result.getMessage()); } diff --git a/src/test/java/com/ycwl/basic/pricing/service/impl/PriceCalculationServiceImplUpgradeCheckTest.java b/src/test/java/com/ycwl/basic/pricing/service/impl/PriceCalculationServiceImplUpgradeCheckTest.java index f7954303..38621d25 100644 --- a/src/test/java/com/ycwl/basic/pricing/service/impl/PriceCalculationServiceImplUpgradeCheckTest.java +++ b/src/test/java/com/ycwl/basic/pricing/service/impl/PriceCalculationServiceImplUpgradeCheckTest.java @@ -1,16 +1,15 @@ package com.ycwl.basic.pricing.service.impl; -import com.ycwl.basic.order.service.IOrderService; -import com.ycwl.basic.pricing.dto.OnePriceInfo; +import com.ycwl.basic.pricing.dto.BundleDiscountInfo; import com.ycwl.basic.pricing.dto.ProductItem; import com.ycwl.basic.pricing.dto.UpgradeCheckRequest; import com.ycwl.basic.pricing.dto.UpgradeCheckResult; import com.ycwl.basic.pricing.entity.PriceBundleConfig; import com.ycwl.basic.pricing.entity.PriceProductConfig; import com.ycwl.basic.pricing.enums.ProductType; +import com.ycwl.basic.pricing.service.IBundleDiscountService; import com.ycwl.basic.pricing.service.ICouponService; import com.ycwl.basic.pricing.service.IDiscountDetectionService; -import com.ycwl.basic.pricing.service.IOnePricePurchaseService; import com.ycwl.basic.pricing.service.IPriceBundleService; import com.ycwl.basic.pricing.service.IProductConfigService; import com.ycwl.basic.pricing.service.IVoucherService; @@ -42,28 +41,26 @@ class PriceCalculationServiceImplUpgradeCheckTest { @Mock private IPriceBundleService bundleService; @Mock - private IOnePricePurchaseService onePricePurchaseService; + private IBundleDiscountService bundleDiscountService; @Mock private IDiscountDetectionService discountDetectionService; @Mock private IVoucherService voucherService; @Mock private IProductTypeCapabilityService productTypeCapabilityService; - @Mock - private IOrderService orderService; @InjectMocks private PriceCalculationServiceImpl priceCalculationService; @Test - void shouldSelectOnePriceWhenUpgradeTypeSpecified() { + void shouldSelectOnePriceWhenCheaper() { mockProductConfig(new BigDecimal("100.00")); - when(onePricePurchaseService.getOnePriceInfo(eq(1L), any())) - .thenReturn(buildOnePriceInfo(new BigDecimal("80.00"))); - when(bundleService.getCheapestBundleConfig(any())) - .thenReturn(buildBundleConfig(new BigDecimal("50.00"))); + when(bundleService.getBundleConfig(any())) + .thenReturn(buildBundleConfig(new BigDecimal("80.00"))); + when(bundleDiscountService.getBestBundleDiscount(any(), eq(1L))) + .thenReturn(buildBundleDiscountInfo(new BigDecimal("10.00"))); - UpgradeCheckRequest request = buildRequest("ONE_PRICE"); + UpgradeCheckRequest request = buildRequest(); UpgradeCheckResult result = priceCalculationService.checkUpgrade(request); assertEquals("ONE_PRICE", result.getBestUpgradeType()); @@ -71,14 +68,14 @@ class PriceCalculationServiceImplUpgradeCheckTest { } @Test - void shouldSelectCheapestBundleWhenUpgradeTypeMissing() { + void shouldSelectBundleDiscountWhenCheaper() { mockProductConfig(new BigDecimal("100.00")); - when(onePricePurchaseService.getOnePriceInfo(eq(1L), any())) - .thenReturn(buildOnePriceInfo(new BigDecimal("80.00"))); - when(bundleService.getCheapestBundleConfig(any())) - .thenReturn(buildBundleConfig(new BigDecimal("70.00"))); + when(bundleService.getBundleConfig(any())) + .thenReturn(buildBundleConfig(new BigDecimal("80.00"))); + when(bundleDiscountService.getBestBundleDiscount(any(), eq(1L))) + .thenReturn(buildBundleDiscountInfo(new BigDecimal("30.00"))); - UpgradeCheckRequest request = buildRequest(null); + UpgradeCheckRequest request = buildRequest(); UpgradeCheckResult result = priceCalculationService.checkUpgrade(request); assertEquals("BUNDLE_DISCOUNT", result.getBestUpgradeType()); @@ -86,14 +83,14 @@ class PriceCalculationServiceImplUpgradeCheckTest { } @Test - void shouldReturnNullBestWhenOnePriceNotApplicable() { + void shouldReturnNullBestWhenNoUpgradeApplicable() { mockProductConfig(new BigDecimal("100.00")); - when(onePricePurchaseService.getOnePriceInfo(eq(1L), any())) - .thenReturn(buildOnePriceInfo(new BigDecimal("120.00"))); - when(bundleService.getCheapestBundleConfig(any())) - .thenReturn(buildBundleConfig(new BigDecimal("70.00"))); + when(bundleService.getBundleConfig(any())) + .thenReturn(null); + when(bundleDiscountService.getBestBundleDiscount(any(), eq(1L))) + .thenReturn(null); - UpgradeCheckRequest request = buildRequest("ONE_PRICE"); + UpgradeCheckRequest request = buildRequest(); UpgradeCheckResult result = priceCalculationService.checkUpgrade(request); assertNull(result.getBestUpgradeType()); @@ -112,15 +109,13 @@ class PriceCalculationServiceImplUpgradeCheckTest { .thenReturn(config); } - private UpgradeCheckRequest buildRequest(String upgradeType) { + private UpgradeCheckRequest buildRequest() { UpgradeCheckRequest request = new UpgradeCheckRequest(); request.setScenicId(1L); request.setFaceId(2L); - request.setMemberId(3L); request.setPaidAmount(BigDecimal.ZERO); request.setPurchasedProducts(List.of()); request.setIntendingProducts(List.of(buildProductItem())); - request.setUpgradeType(upgradeType); return request; } @@ -133,17 +128,6 @@ class PriceCalculationServiceImplUpgradeCheckTest { return item; } - private OnePriceInfo buildOnePriceInfo(BigDecimal onePrice) { - OnePriceInfo info = new OnePriceInfo(); - info.setConfigId(10L); - info.setConfigName("一口价"); - info.setScenicId(1L); - info.setOnePrice(onePrice); - info.setOriginalPrice(onePrice); - info.setDescription("一口价测试"); - return info; - } - private PriceBundleConfig buildBundleConfig(BigDecimal bundlePrice) { PriceBundleConfig config = new PriceBundleConfig(); config.setId(20L); @@ -153,4 +137,17 @@ class PriceCalculationServiceImplUpgradeCheckTest { config.setDescription("打包购买测试"); return config; } + + private BundleDiscountInfo buildBundleDiscountInfo(BigDecimal discountAmount) { + BundleDiscountInfo info = new BundleDiscountInfo(); + info.setBundleConfigId(30L); + info.setBundleName("打包购买"); + info.setBundleDescription("打包购买测试"); + info.setDiscountType("FIXED_DISCOUNT"); + info.setDiscountValue(discountAmount); + info.setActualDiscountAmount(discountAmount); + info.setMinQuantity(1); + info.setMinAmount(BigDecimal.ZERO); + return info; + } } diff --git a/src/test/java/com/ycwl/basic/product/service/ProductTypeCapabilityServiceTest.java b/src/test/java/com/ycwl/basic/product/service/ProductTypeCapabilityServiceTest.java index fd339a19..14a8cafa 100644 --- a/src/test/java/com/ycwl/basic/product/service/ProductTypeCapabilityServiceTest.java +++ b/src/test/java/com/ycwl/basic/product/service/ProductTypeCapabilityServiceTest.java @@ -30,7 +30,7 @@ public class ProductTypeCapabilityServiceTest { assertNotNull(capability); assertEquals("VLOG_VIDEO", capability.getProductType()); assertEquals("Vlog视频", capability.getDisplayName()); - assertEquals("VIDEO", capability.getCategory()); + assertEquals("VLOG", capability.getCategory()); assertEquals(PricingMode.FIXED, capability.getPricingModeEnum()); assertEquals(false, capability.getAllowDuplicatePurchase()); assertEquals(DuplicateCheckStrategy.UNIQUE_RESOURCE, capability.getDuplicateCheckStrategyEnum());