test: 新增 StudySessionsEntity 单元测试 (16 cases)
覆盖场景:直接结束、暂停后结束、暂停继续再结束、多次暂停继续、 边界值(10分钟)、极短时间、已结束会话、PAUSED 状态直接结束等
This commit is contained in:
@@ -0,0 +1,301 @@
|
||||
package com.guo.learningprogresstracker.entity;
|
||||
|
||||
import com.guo.learningprogresstracker.enums.StudySessionStateEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class StudySessionsEntityTest {
|
||||
|
||||
private StudySessionsEntity createOngoingSession(int minutesAgo) {
|
||||
StudySessionsEntity session = new StudySessionsEntity();
|
||||
session.setSessionNum("SESSION_TEST");
|
||||
session.setStartTime(LocalDateTime.now().minusMinutes(minutesAgo));
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(minutesAgo));
|
||||
session.setEffectiveTime(0);
|
||||
session.setActualTime(0);
|
||||
session.setSessionState(StudySessionStateEnum.ONGOING.name());
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景1:直接结束,有效时间 < 10分钟 → effectiveTime 应被清零
|
||||
*/
|
||||
@Test
|
||||
void endedSession_effectiveTimeLessThan10Min_shouldZeroOut() {
|
||||
StudySessionsEntity session = createOngoingSession(5);
|
||||
session.endedStudySession();
|
||||
|
||||
assertEquals(0, session.getEffectiveTime(), "有效时间不足10分钟应被清零");
|
||||
assertEquals(0, session.getEffectivenessRatio(), "有效时间比应被清零");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景2:直接结束,有效时间 = 10分钟(边界值)→ 保留(600 不 < 600)
|
||||
*/
|
||||
@Test
|
||||
void endedSession_effectiveTimeExactly10Min_shouldKeep() {
|
||||
StudySessionsEntity session = createOngoingSession(10);
|
||||
session.endedStudySession();
|
||||
|
||||
assertTrue(session.getEffectiveTime() >= 10 * 60, "有效时间等于10分钟应保留(阈值为 < 600)");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景3:直接结束,有效时间 > 10分钟 → effectiveTime 应保留
|
||||
*/
|
||||
@Test
|
||||
void endedSession_effectiveTimeMoreThan10Min_shouldKeep() {
|
||||
StudySessionsEntity session = createOngoingSession(15);
|
||||
session.endedStudySession();
|
||||
|
||||
assertTrue(session.getEffectiveTime() >= 15 * 60, "有效时间超过10分钟应保留");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景4:暂停后直接结束(未继续),暂停段 < 10分钟 → 清零
|
||||
*/
|
||||
@Test
|
||||
void endedSession_pausedThenEnded_lessThan10Min_shouldZeroOut() {
|
||||
StudySessionsEntity session = createOngoingSession(5);
|
||||
session.pausedStudySession(LocalDateTime.now());
|
||||
assertEquals(StudySessionStateEnum.PAUSED.name(), session.getSessionState());
|
||||
assertTrue(session.getEffectiveTime() > 0, "暂停后应有有效时间");
|
||||
|
||||
session.endedStudySession();
|
||||
|
||||
assertEquals(0, session.getEffectiveTime(), "暂停后结束,有效时间不足10分钟应清零");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景5:暂停后继续,再结束,总有效时间 < 10分钟 → 清零
|
||||
*/
|
||||
@Test
|
||||
void endedSession_pausedContinuedThenEnded_lessThan10Min_shouldZeroOut() throws Exception {
|
||||
StudySessionsEntity session = createOngoingSession(8);
|
||||
// 暂停(累加3分钟:从8分钟前到5分钟前)
|
||||
session.pausedStudySession(LocalDateTime.now().minusMinutes(5));
|
||||
|
||||
// 继续学习,模拟又学习了2分钟
|
||||
session.continueStudySession();
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(2));
|
||||
|
||||
session.endedStudySession();
|
||||
|
||||
// 总有效时间 ≈ 3+2 = 5分钟 < 10分钟 → 清零
|
||||
assertEquals(0, session.getEffectiveTime(), "总有效时间不足10分钟应清零");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景6:暂停后继续,再结束,总有效时间 > 10分钟 → 保留
|
||||
*/
|
||||
@Test
|
||||
void endedSession_pausedContinuedThenEnded_moreThan10Min_shouldKeep() throws Exception {
|
||||
StudySessionsEntity session = createOngoingSession(20);
|
||||
// 暂停(累加8分钟:从20分钟前到12分钟前)
|
||||
session.pausedStudySession(LocalDateTime.now().minusMinutes(12));
|
||||
|
||||
// 继续学习,模拟又学习了12分钟
|
||||
session.continueStudySession();
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(12));
|
||||
|
||||
session.endedStudySession();
|
||||
|
||||
// 总有效时间 ≈ 8+12 = 20分钟 > 10分钟 → 保留
|
||||
assertTrue(session.getEffectiveTime() > 0, "总有效时间超过10分钟应保留");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景7:多次暂停-继续,总有效时间 < 10分钟 → 清零
|
||||
*/
|
||||
@Test
|
||||
void endedSession_multiplePauseContinue_lessThan10Min_shouldZeroOut() throws Exception {
|
||||
StudySessionsEntity session = createOngoingSession(15);
|
||||
// 第一段:3分钟(15分钟前 → 12分钟前)
|
||||
session.pausedStudySession(LocalDateTime.now().minusMinutes(12));
|
||||
// 继续,模拟第二段学习3分钟(12分钟前 → 9分钟前)
|
||||
session.continueStudySession();
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(9));
|
||||
|
||||
// 第二段暂停,累加3分钟
|
||||
session.pausedStudySession(LocalDateTime.now().minusMinutes(6));
|
||||
// 继续,模拟第三段学习3分钟(6分钟前 → 3分钟前)
|
||||
session.continueStudySession();
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(3));
|
||||
|
||||
// 总计 3+3+3 = 9分钟 < 10分钟
|
||||
session.endedStudySession();
|
||||
|
||||
assertEquals(0, session.getEffectiveTime(), "多次暂停继续,总有效时间不足10分钟应清零");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景8:多次暂停-继续,总有效时间 > 10分钟 → 保留
|
||||
*/
|
||||
@Test
|
||||
void endedSession_multiplePauseContinue_moreThan10Min_shouldKeep() throws Exception {
|
||||
StudySessionsEntity session = createOngoingSession(25);
|
||||
// 第一段:5分钟(25分钟前 → 20分钟前)
|
||||
session.pausedStudySession(LocalDateTime.now().minusMinutes(20));
|
||||
// 继续,模拟第二段学习5分钟
|
||||
session.continueStudySession();
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(15));
|
||||
|
||||
// 第二段暂停,累加5分钟
|
||||
session.pausedStudySession(LocalDateTime.now().minusMinutes(10));
|
||||
// 继续,模拟第三段学习5分钟
|
||||
session.continueStudySession();
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(5));
|
||||
|
||||
// 总计 5+5+5 = 15分钟 > 10分钟
|
||||
session.endedStudySession();
|
||||
|
||||
assertTrue(session.getEffectiveTime() > 0, "多次暂停继续,总有效时间超过10分钟应保留");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景9:已结束的会话再次结束 → 不应重复处理
|
||||
*/
|
||||
@Test
|
||||
void endedSession_alreadyEnded_shouldNotChange() {
|
||||
StudySessionsEntity session = createOngoingSession(5);
|
||||
session.endedStudySession();
|
||||
double effectiveTimeAfterFirstEnd = session.getEffectiveTime();
|
||||
|
||||
session.endedStudySession();
|
||||
|
||||
assertEquals(effectiveTimeAfterFirstEnd, session.getEffectiveTime(), "已结束的会话不应重复处理");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景10:有效时间非常短(1分钟) → 清零
|
||||
*/
|
||||
@Test
|
||||
void endedSession_veryShortSession_shouldZeroOut() {
|
||||
StudySessionsEntity session = createOngoingSession(1);
|
||||
session.endedStudySession();
|
||||
|
||||
assertEquals(0, session.getEffectiveTime(), "极短会话的有效时间应被清零");
|
||||
assertEquals(0, session.getEffectivenessRatio());
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景11:有效时间恰好超过阈值(11分钟) → 保留
|
||||
*/
|
||||
@Test
|
||||
void endedSession_justOverThreshold_shouldKeep() {
|
||||
StudySessionsEntity session = createOngoingSession(11);
|
||||
session.endedStudySession();
|
||||
|
||||
assertTrue(session.getEffectiveTime() > 0, "超过阈值的有效时间应保留");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景12:暂停期间不应计入有效时间,只计实际学习的段
|
||||
*/
|
||||
@Test
|
||||
void endedSession_pauseTimeNotCounted_shouldCalcCorrectly() throws Exception {
|
||||
StudySessionsEntity session = createOngoingSession(30);
|
||||
// 学习5分钟(30分钟前 → 25分钟前)
|
||||
session.pausedStudySession(LocalDateTime.now().minusMinutes(25));
|
||||
double firstSegment = session.getEffectiveTime();
|
||||
assertTrue(firstSegment >= 5 * 60 - 1 && firstSegment <= 5 * 60 + 1,
|
||||
"第一段有效时间应约5分钟,实际: " + firstSegment);
|
||||
|
||||
// 暂停20分钟(不应计入有效时间)
|
||||
|
||||
// 继续学习4分钟
|
||||
session.continueStudySession();
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(4));
|
||||
|
||||
session.endedStudySession();
|
||||
|
||||
// 有效时间应约为 5+4=9分钟 < 10分钟 → 清零
|
||||
assertEquals(0, session.getEffectiveTime(), "暂停期间不应计入有效时间,9分钟 < 10分钟阈值应清零");
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景13:暂停后继续,有效时间恰好在阈值边界 → 验证边界精度
|
||||
*/
|
||||
@Test
|
||||
void endedSession_borderlineWithPause_shouldHandleCorrectly() throws Exception {
|
||||
StudySessionsEntity session = createOngoingSession(20);
|
||||
// 第一段:6分钟(20分钟前 → 14分钟前)
|
||||
session.pausedStudySession(LocalDateTime.now().minusMinutes(14));
|
||||
|
||||
// 继续,模拟第二段学习5分钟
|
||||
session.continueStudySession();
|
||||
session.setLastStartTime(LocalDateTime.now().minusMinutes(5));
|
||||
|
||||
// 总计 6+5 = 11分钟 > 10分钟 → 保留
|
||||
session.endedStudySession();
|
||||
|
||||
assertTrue(session.getEffectiveTime() > 0, "总计11分钟应超过阈值被保留");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景14:ONGOING 状态直接结束,effectiveTime 为 0(刚开始就结束) → 0 < 600 → 清零
|
||||
*/
|
||||
@Test
|
||||
void endedSession_immediatelyEnded_shouldZeroOut() {
|
||||
StudySessionsEntity session = new StudySessionsEntity();
|
||||
session.setSessionNum("SESSION_INSTANT");
|
||||
session.setStartTime(LocalDateTime.now());
|
||||
session.setLastStartTime(LocalDateTime.now());
|
||||
session.setEffectiveTime(0);
|
||||
session.setActualTime(0);
|
||||
session.setSessionState(StudySessionStateEnum.ONGOING.name());
|
||||
|
||||
session.endedStudySession();
|
||||
|
||||
assertEquals(0, session.getEffectiveTime(), "刚开始就结束,有效时间应为0");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景15:暂停后直接结束(PAUSED 状态),有效时间 < 10分钟 → 清零
|
||||
*/
|
||||
@Test
|
||||
void endedSession_pausedThenDirectlyEnded_lessThan10Min_shouldZeroOut() {
|
||||
StudySessionsEntity session = createOngoingSession(7);
|
||||
// 暂停(累加7分钟有效时间)
|
||||
session.pausedStudySession(LocalDateTime.now());
|
||||
session.setEffectiveTime(7 * 60); // 精确设置为7分钟
|
||||
|
||||
// PAUSED 状态直接结束(不经过 ONGOING)
|
||||
session.endedStudySession();
|
||||
|
||||
assertEquals(0, session.getEffectiveTime(), "PAUSED 状态结束,7分钟 < 10分钟应清零");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景16:暂停后直接结束(PAUSED 状态),有效时间 > 10分钟 → 保留
|
||||
*/
|
||||
@Test
|
||||
void endedSession_pausedThenDirectlyEnded_moreThan10Min_shouldKeep() {
|
||||
StudySessionsEntity session = createOngoingSession(15);
|
||||
// 暂停(累加15分钟有效时间)
|
||||
session.pausedStudySession(LocalDateTime.now());
|
||||
|
||||
// PAUSED 状态直接结束
|
||||
session.endedStudySession();
|
||||
|
||||
assertTrue(session.getEffectiveTime() > 0, "PAUSED 状态结束,15分钟 > 10分钟应保留");
|
||||
assertEquals(StudySessionStateEnum.ENDED.name(), session.getSessionState());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user