“mitao”
2026-04-10 1e72a0b06e37d372c46522c85c6733edbcd5331d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package com.tcm.training.admin.live.service;
 
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.tcm.training.admin.live.entity.LiveSession;
import com.tcm.training.admin.live.mapper.LiveSessionMapper;
import com.tcm.training.admin.live.vo.LiveSessionStatusVO;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
 
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
 
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
 
/**
 * 直播场次自动开播定时任务测试。
 */
@ExtendWith(MockitoExtension.class)
class LiveSessionStatusSyncServiceTest {
 
    @BeforeAll
    static void initLambdaCache() {
        MapperBuilderAssistant assistant = new MapperBuilderAssistant(new MybatisConfiguration(), "");
        TableInfoHelper.initTableInfo(assistant, LiveSession.class);
    }
 
    @Mock
    private LiveSessionMapper liveSessionMapper;
 
    @Mock
    private LiveSessionAppService liveSessionAppService;
 
    private LiveSessionStatusSyncService liveSessionStatusSyncService;
 
    /**
     * 每个用例前重建被测定时任务服务。
     */
    @BeforeEach
    void setUp() {
        liveSessionStatusSyncService = new LiveSessionStatusSyncService(liveSessionMapper, liveSessionAppService);
    }
 
    /**
     * 已到开播时间的未开始场次应触发自动开播。
     */
    @Test
    void syncDueSessionsShouldAutoStartPendingSessions() {
        LiveSession sessionA = buildSession(10001L, 9000L);
        LiveSession sessionB = buildSession(10002L, 9000L);
        when(liveSessionMapper.selectList(any())).thenReturn(Arrays.asList(sessionA, sessionB));
        when(liveSessionAppService.autoStart(org.mockito.ArgumentMatchers.eq(10001L), any(LocalDateTime.class)))
                .thenReturn(new LiveSessionStatusVO(10001L, 1, LocalDateTime.of(2026, 4, 9, 10, 0), null));
        when(liveSessionAppService.autoStart(org.mockito.ArgumentMatchers.eq(10002L), any(LocalDateTime.class)))
                .thenReturn(new LiveSessionStatusVO(10002L, 1, LocalDateTime.of(2026, 4, 9, 10, 0), null));
 
        liveSessionStatusSyncService.syncDueSessions();
 
        verify(liveSessionAppService).autoStart(org.mockito.ArgumentMatchers.eq(10001L), any(LocalDateTime.class));
        verify(liveSessionAppService).autoStart(org.mockito.ArgumentMatchers.eq(10002L), any(LocalDateTime.class));
    }
 
    /**
     * 没有命中场次时不应触发任何状态迁移。
     */
    @Test
    void syncDueSessionsShouldSkipWhenNoPendingSession() {
        when(liveSessionMapper.selectList(any())).thenReturn(Collections.<LiveSession>emptyList());
 
        liveSessionStatusSyncService.syncDueSessions();
 
        verify(liveSessionAppService, never()).autoStart(any(Long.class), any(LocalDateTime.class));
    }
 
    /**
     * 即使没有待开播场次,也应定时收敛历史残留的直播中课程状态。
     */
    @Test
    void syncDueSessionsShouldReconcileHistoricalLivingCourses() {
        LiveSession staleLivingSession = new LiveSession();
        staleLivingSession.setId(10009L);
        staleLivingSession.setLiveCourseId(9001L);
        staleLivingSession.setLiveStatus(1);
        staleLivingSession.setStartTime(LocalDateTime.of(2026, 4, 8, 10, 0));
 
        when(liveSessionMapper.selectList(any())).thenReturn(
                Collections.<LiveSession>emptyList(),
                Collections.singletonList(staleLivingSession)
        );
        when(liveSessionAppService.reconcileCourseLivingSessions(org.mockito.ArgumentMatchers.eq(9001L), any(LocalDateTime.class)))
                .thenReturn(1);
 
        liveSessionStatusSyncService.syncDueSessions();
 
        verify(liveSessionAppService).reconcileCourseLivingSessions(org.mockito.ArgumentMatchers.eq(9001L), any(LocalDateTime.class));
    }
 
    /**
     * 构造待自动开播的场次样例。
     */
    private LiveSession buildSession(Long sessionId, Long courseId) {
        LiveSession session = new LiveSession();
        session.setId(sessionId);
        session.setLiveCourseId(courseId);
        session.setLiveStatus(0);
        session.setStartTime(LocalDateTime.of(2026, 4, 9, 10, 0));
        session.setDeleted(0);
        return session;
    }
}