7a55063174
覆盖场景:暂停调用 API 并更新状态、继续调用 continueSession API、 ONGOING 状态不误触发 continue、结束会话 API、多次暂停/继续完整流程
277 lines
8.6 KiB
TypeScript
277 lines
8.6 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { ref, reactive } from 'vue'
|
|
|
|
// Mock API
|
|
vi.mock('@/api/studySessions', () => ({
|
|
continueSession: vi.fn(),
|
|
pauseSession: vi.fn(),
|
|
endSession: vi.fn(),
|
|
startOrContinueStudySession: vi.fn(),
|
|
getSessionDetail: vi.fn(),
|
|
}))
|
|
|
|
vi.mock('@/api/reportFragments', () => ({
|
|
getFragmentsBySession: vi.fn(),
|
|
updateFragments: vi.fn(),
|
|
}))
|
|
|
|
import {
|
|
continueSession,
|
|
pauseSession,
|
|
endSession,
|
|
startOrContinueStudySession,
|
|
} from '@/api/studySessions'
|
|
|
|
const mockedContinueSession = vi.mocked(continueSession)
|
|
const mockedPauseSession = vi.mocked(pauseSession)
|
|
const mockedEndSession = vi.mocked(endSession)
|
|
const mockedStartOrContinue = vi.mocked(startOrContinueStudySession)
|
|
|
|
// 模拟 StartTask.vue 中的核心状态和方法
|
|
function createSessionSimulator() {
|
|
const taskInfo = reactive({
|
|
sessionNum: 'SESSION_001',
|
|
sessionState: 'ONGOING' as string,
|
|
taskName: '测试任务',
|
|
taskNum: 'T001',
|
|
startTime: '',
|
|
endTime: '',
|
|
lastStartTime: '',
|
|
actualTime: 0,
|
|
effectiveTime: 0,
|
|
effectivenessRatio: '--',
|
|
pointerPosition: 1500000,
|
|
systemMessage: '',
|
|
})
|
|
|
|
const timerRunning = ref(true)
|
|
|
|
const clear = () => {
|
|
timerRunning.value = false
|
|
}
|
|
|
|
const runCountdown = (duration: number) => {
|
|
timerRunning.value = true
|
|
}
|
|
|
|
// 从 StartTask.vue 提取的 stopTimer 逻辑
|
|
const stopTimer = async () => {
|
|
const res = await pauseSession(taskInfo.sessionNum)
|
|
if (res.code === 200) {
|
|
taskInfo.sessionState = 'PAUSED'
|
|
}
|
|
clear()
|
|
}
|
|
|
|
// 从 StartTask.vue 提取的 startTimer 逻辑
|
|
const startTimer = async () => {
|
|
if (taskInfo.sessionState === 'PAUSED') {
|
|
const res = await continueSession(taskInfo.sessionNum)
|
|
if (res.code === 200) {
|
|
// ElMessage.success("任务继续")
|
|
}
|
|
// loadTaskSession 模拟
|
|
const sessionRes = await startOrContinueStudySession(taskInfo.taskNum)
|
|
Object.assign(taskInfo, sessionRes.data)
|
|
}
|
|
const duration = taskInfo.pointerPosition || 25 * 60 * 1000
|
|
runCountdown(duration)
|
|
}
|
|
|
|
// 从 StartTask.vue 提取的 endTimer 逻辑(简化版,跳过 confirm)
|
|
const endTimer = async (content: string) => {
|
|
if (!content) return
|
|
const res = await endSession(taskInfo.sessionNum, content)
|
|
if (res.code === 200) {
|
|
if (res.message && res.message !== '请求成功') {
|
|
// ElMessage.warning(res.message)
|
|
}
|
|
}
|
|
clear()
|
|
}
|
|
|
|
return { taskInfo, timerRunning, stopTimer, startTimer, endTimer, clear }
|
|
}
|
|
|
|
describe('StartTask.vue 暂停/继续逻辑', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
describe('stopTimer - 暂停', () => {
|
|
it('调用 pauseSession API', async () => {
|
|
mockedPauseSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
const { stopTimer } = createSessionSimulator()
|
|
|
|
await stopTimer()
|
|
|
|
expect(mockedPauseSession).toHaveBeenCalledWith('SESSION_001')
|
|
})
|
|
|
|
it('暂停成功后 sessionState 应更新为 PAUSED', async () => {
|
|
mockedPauseSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
const { taskInfo, stopTimer } = createSessionSimulator()
|
|
|
|
expect(taskInfo.sessionState).toBe('ONGOING')
|
|
await stopTimer()
|
|
expect(taskInfo.sessionState).toBe('PAUSED')
|
|
})
|
|
|
|
it('暂停后 timerRunning 应为 false', async () => {
|
|
mockedPauseSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
const { timerRunning, stopTimer } = createSessionSimulator()
|
|
|
|
expect(timerRunning.value).toBe(true)
|
|
await stopTimer()
|
|
expect(timerRunning.value).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('startTimer - 继续', () => {
|
|
it('PAUSED 状态下点击开始,应调用 continueSession API', async () => {
|
|
mockedPauseSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
mockedContinueSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
mockedStartOrContinue.mockResolvedValue({
|
|
code: 200,
|
|
data: {
|
|
sessionNum: 'SESSION_001',
|
|
sessionState: 'ONGOING',
|
|
pointerPosition: 1500000,
|
|
},
|
|
} as any)
|
|
|
|
const { taskInfo, stopTimer, startTimer } = createSessionSimulator()
|
|
|
|
// 先暂停
|
|
await stopTimer()
|
|
expect(taskInfo.sessionState).toBe('PAUSED')
|
|
|
|
// 再开始
|
|
await startTimer()
|
|
|
|
expect(mockedContinueSession).toHaveBeenCalledWith('SESSION_001')
|
|
})
|
|
|
|
it('PAUSED 状态下点击开始,应调用 loadTaskSession 刷新数据', async () => {
|
|
mockedPauseSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
mockedContinueSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
mockedStartOrContinue.mockResolvedValue({
|
|
code: 200,
|
|
data: {
|
|
sessionNum: 'SESSION_001',
|
|
sessionState: 'ONGOING',
|
|
pointerPosition: 1200000,
|
|
},
|
|
} as any)
|
|
|
|
const { taskInfo, stopTimer, startTimer } = createSessionSimulator()
|
|
|
|
await stopTimer()
|
|
await startTimer()
|
|
|
|
expect(mockedStartOrContinue).toHaveBeenCalledWith('T001')
|
|
expect(taskInfo.sessionState).toBe('ONGOING')
|
|
})
|
|
|
|
it('ONGOING 状态下点击开始,不应调用 continueSession API', async () => {
|
|
mockedStartOrContinue.mockResolvedValue({
|
|
code: 200,
|
|
data: { sessionState: 'ONGOING', pointerPosition: 1500000 },
|
|
} as any)
|
|
|
|
const { taskInfo, startTimer } = createSessionSimulator()
|
|
|
|
// 直接在 ONGOING 状态调用 startTimer
|
|
expect(taskInfo.sessionState).toBe('ONGOING')
|
|
await startTimer()
|
|
|
|
expect(mockedContinueSession).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('开始后 timerRunning 应为 true', async () => {
|
|
mockedPauseSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
mockedContinueSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
mockedStartOrContinue.mockResolvedValue({
|
|
code: 200,
|
|
data: { sessionState: 'ONGOING', pointerPosition: 1500000 },
|
|
} as any)
|
|
|
|
const { timerRunning, stopTimer, startTimer } = createSessionSimulator()
|
|
|
|
await stopTimer()
|
|
expect(timerRunning.value).toBe(false)
|
|
|
|
await startTimer()
|
|
expect(timerRunning.value).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('endTimer - 结束会话', () => {
|
|
it('调用 endSession API 并传递 content', async () => {
|
|
mockedEndSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
const { endTimer } = createSessionSimulator()
|
|
|
|
await endTimer('学习总结内容')
|
|
|
|
expect(mockedEndSession).toHaveBeenCalledWith('SESSION_001', '学习总结内容')
|
|
})
|
|
|
|
it('后端返回 warning 消息时,message 应包含提示信息', async () => {
|
|
mockedEndSession.mockResolvedValue({
|
|
code: 200,
|
|
message: '本次有效学习时间不足10分钟,不计入总学习时间',
|
|
} as any)
|
|
|
|
const { endTimer } = createSessionSimulator()
|
|
const res = await endSession('SESSION_001', '内容')
|
|
|
|
expect(res.message).toBe('本次有效学习时间不足10分钟,不计入总学习时间')
|
|
expect(res.message).not.toBe('请求成功')
|
|
})
|
|
|
|
it('content 为空时不调用 API', async () => {
|
|
const { endTimer } = createSessionSimulator()
|
|
|
|
await endTimer('')
|
|
|
|
expect(mockedEndSession).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('完整暂停→继续→暂停流程', () => {
|
|
it('多次暂停/继续应正确更新状态和调用 API', async () => {
|
|
mockedPauseSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
mockedContinueSession.mockResolvedValue({ code: 200, message: '请求成功' } as any)
|
|
mockedStartOrContinue.mockResolvedValue({
|
|
code: 200,
|
|
data: { sessionState: 'ONGOING', pointerPosition: 1500000 },
|
|
} as any)
|
|
|
|
const { taskInfo, stopTimer, startTimer } = createSessionSimulator()
|
|
|
|
// 初始状态
|
|
expect(taskInfo.sessionState).toBe('ONGOING')
|
|
|
|
// 第一次暂停
|
|
await stopTimer()
|
|
expect(taskInfo.sessionState).toBe('PAUSED')
|
|
expect(mockedPauseSession).toHaveBeenCalledTimes(1)
|
|
|
|
// 继续
|
|
await startTimer()
|
|
expect(taskInfo.sessionState).toBe('ONGOING')
|
|
expect(mockedContinueSession).toHaveBeenCalledTimes(1)
|
|
|
|
// 第二次暂停
|
|
await stopTimer()
|
|
expect(taskInfo.sessionState).toBe('PAUSED')
|
|
expect(mockedPauseSession).toHaveBeenCalledTimes(2)
|
|
|
|
// 再次继续
|
|
await startTimer()
|
|
expect(taskInfo.sessionState).toBe('ONGOING')
|
|
expect(mockedContinueSession).toHaveBeenCalledTimes(2)
|
|
})
|
|
})
|
|
})
|