Junjie
2026-04-27 2cc61346cc0a3e5338aa8957f79f4c99c204f339
src/test/java/com/zy/ai/service/AutoTuneApplyServiceImplTest.java
@@ -11,10 +11,12 @@
import com.zy.asrs.entity.BasDualCrnp;
import com.zy.asrs.entity.BasStation;
import com.zy.asrs.entity.StationFlowCapacity;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasCrnpService;
import com.zy.asrs.service.BasDualCrnpService;
import com.zy.asrs.service.BasStationService;
import com.zy.asrs.service.StationFlowCapacityService;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.utils.RedisUtil;
import com.zy.core.enums.RedisKeyType;
import com.zy.system.entity.Config;
@@ -79,6 +81,8 @@
    @Mock
    private StationFlowCapacityService stationFlowCapacityService;
    @Mock
    private WrkMastService wrkMastService;
    @Mock
    private RedisUtil redisUtil;
    private RecordingTransactionManager transactionManager;
@@ -93,6 +97,7 @@
        ReflectionTestUtils.setField(service, "basCrnpService", basCrnpService);
        ReflectionTestUtils.setField(service, "basDualCrnpService", basDualCrnpService);
        ReflectionTestUtils.setField(service, "stationFlowCapacityService", stationFlowCapacityService);
        ReflectionTestUtils.setField(service, "wrkMastService", wrkMastService);
        ReflectionTestUtils.setField(service, "transactionManager", transactionManager);
        ReflectionTestUtils.setField(service, "redisUtil", redisUtil);
@@ -109,6 +114,7 @@
        });
        when(aiAutoTuneChangeService.saveBatch(any(Collection.class))).thenReturn(true);
        when(aiAutoTuneChangeService.list(any(Wrapper.class))).thenReturn(Collections.emptyList());
        when(wrkMastService.count(any(Wrapper.class))).thenReturn(0L);
        when(configService.getConfigValue(eq("aiAutoTuneIntervalMinutes"), any())).thenReturn("10");
        when(configService.saveConfigValue(any(), any())).thenReturn(true);
        when(basStationService.update(any(Wrapper.class))).thenReturn(true);
@@ -206,6 +212,44 @@
    }
    @Test
    void rejectStationOutTaskLimitNullUnlimitedCurrentValue() {
        when(basStationService.getById(101)).thenReturn(station(101, null));
        service.apply(request(true, command("station", "101", "outTaskLimit", "1")));
        List<AiAutoTuneChange> changes = savedChanges();
        assertEquals("rejected", changes.get(0).getResultStatus());
        assertTrue(changes.get(0).getRejectReason().contains("需要人工先初始化为有限值"));
        verify(stationFlowCapacityService, never()).getOne(any(Wrapper.class));
    }
    @Test
    void rejectStationOutTaskLimitNegativeUnlimitedCurrentValue() {
        when(basStationService.getById(101)).thenReturn(station(101, -1));
        service.apply(request(true, command("station", "101", "outTaskLimit", "1")));
        List<AiAutoTuneChange> changes = savedChanges();
        assertEquals("rejected", changes.get(0).getResultStatus());
        assertTrue(changes.get(0).getRejectReason().contains("需要人工先初始化为有限值"));
        verify(stationFlowCapacityService, never()).getOne(any(Wrapper.class));
    }
    @Test
    void allowStationOutTaskLimitZeroToOneAsFiniteStep() {
        when(basStationService.getById(101)).thenReturn(station(101, 0));
        when(stationFlowCapacityService.getOne(any(Wrapper.class))).thenReturn(capacity(101, "OUT", 1));
        AutoTuneApplyResult result = service.apply(request(true, command("station", "101", "outTaskLimit", "1")));
        List<AiAutoTuneChange> changes = savedChanges();
        assertTrue(result.getSuccess());
        assertEquals("dry_run", changes.get(0).getResultStatus());
        assertEquals("0", changes.get(0).getOldValue());
        assertEquals("1", changes.get(0).getRequestedValue());
    }
    @Test
    void rejectCooldownHit() {
        when(configService.getOne(any(Wrapper.class))).thenReturn(config("conveyorStationTaskLimit", "10"));
        AiAutoTuneChange cooldownChange = new AiAutoTuneChange();
@@ -252,6 +296,46 @@
        verify(basStationService, never()).update(any(Wrapper.class));
        verify(basCrnpService, never()).update(any(Wrapper.class));
        verify(basDualCrnpService, never()).update(any(Wrapper.class));
    }
    @Test
    void applyJobRecordsActiveTasksWhenCountIsPositive() {
        when(configService.getOne(any(Wrapper.class))).thenReturn(config("conveyorStationTaskLimit", "10"));
        when(wrkMastService.count(any(Wrapper.class))).thenReturn(1L);
        service.apply(request(true, command("sys_config", null, "conveyorStationTaskLimit", "15")));
        AiAutoTuneJob updatedJob = updatedJob();
        assertEquals(1, updatedJob.getHasActiveTasks());
        ArgumentCaptor<Wrapper<WrkMast>> captor = ArgumentCaptor.forClass(Wrapper.class);
        verify(wrkMastService).count(captor.capture());
        String sqlSegment = captor.getValue().getSqlSegment();
        assertTrue(sqlSegment.contains("NOT IN"));
        assertTrue(sqlSegment.contains("OR"));
        assertTrue(sqlSegment.contains("wrk_sts IS NULL"));
    }
    @Test
    void applyJobRecordsNoActiveTasksWhenCountIsZero() {
        when(configService.getOne(any(Wrapper.class))).thenReturn(config("conveyorStationTaskLimit", "10"));
        when(wrkMastService.count(any(Wrapper.class))).thenReturn(0L);
        service.apply(request(true, command("sys_config", null, "conveyorStationTaskLimit", "15")));
        AiAutoTuneJob updatedJob = updatedJob();
        assertEquals(0, updatedJob.getHasActiveTasks());
    }
    @Test
    void applyJobFallsBackToNoActiveTasksWhenCountFails() {
        when(configService.getOne(any(Wrapper.class))).thenReturn(config("conveyorStationTaskLimit", "10"));
        when(wrkMastService.count(any(Wrapper.class))).thenThrow(new IllegalStateException("count failed"));
        service.apply(request(true, command("sys_config", null, "conveyorStationTaskLimit", "15")));
        AiAutoTuneJob updatedJob = updatedJob();
        assertEquals(0, updatedJob.getHasActiveTasks());
    }
    @Test
@@ -493,6 +577,23 @@
    }
    @Test
    void rollbackJobRecordsActiveTasksWhenCountIsPositive() {
        AiAutoTuneJob latestRealJob = job(10L, "manual", "success");
        AiAutoTuneChange configChange = successChange(10L, "sys_config", "", "conveyorStationTaskLimit", "10", "15");
        when(wrkMastService.count(any(Wrapper.class))).thenReturn(1L);
        when(aiAutoTuneChangeService.list(any(Wrapper.class)))
                .thenReturn(List.of(configChange))
                .thenReturn(List.of(configChange));
        when(aiAutoTuneJobService.getById(10L)).thenReturn(latestRealJob);
        when(configService.getOne(any(Wrapper.class))).thenReturn(config("conveyorStationTaskLimit", "15"));
        service.rollbackLastSuccessfulJob("manual rollback");
        AiAutoTuneJob updatedJob = updatedJob();
        assertEquals(1, updatedJob.getHasActiveTasks());
    }
    @Test
    void rollbackCacheRefreshFailureDoesNotAppendFailedAuditOrJob() {
        AiAutoTuneJob latestRealJob = job(10L, "manual", "success");
        AiAutoTuneChange configChange = successChange(10L, "sys_config", "", "conveyorStationTaskLimit", "10", "15");