You've already forked FrameTour-BE
test(pipeline): 更新人脸识别流水线集成测试配置
- 替换 Spring Boot 测试注解为 Mockito 扩展 - 添加所有流水线阶段的 Mock 对象注入 - 更新自动匹配旧版本流水线的阶段数量断言 - 在多个阶段测试中添加 FaceStatusManager 的 Mock 验证 - 修改价格计算服务升级检查测试的业务逻辑验证 - 修复产品类型能力服务中的类别常量值
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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<FaceMatchingContext> 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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<MemberSourceEntity> createMemberSourceList(int count) {
|
||||
|
||||
@@ -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<FaceMatchingContext> 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<FaceMatchingContext> 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class PipelineBuilderTest {
|
||||
|
||||
Exception exception = assertThrows(IllegalStateException.class, builder::build);
|
||||
|
||||
assertEquals("管线至少需要一个Stage", exception.getMessage());
|
||||
assertEquals("Pipeline 至少需要一个 Stage", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user