/** * 员工导入状态持久化功能测试用例 * * 测试目标:验证导入状态跨页面持久化功能 * * 测试场景: * 1. 导入成功场景(全部成功) * 2. 导入部分失败场景 * 3. 刷新页面后状态恢复 * 4. localStorage过期处理 * 5. 清除导入历史功能 */ const BASE_URL = 'http://localhost:8080'; // 测试账号 const TEST_CREDENTIALS = { username: 'admin', password: 'admin123' }; let authToken = ''; /** * 登录获取token */ async function login() { console.log('\n=== 步骤1: 登录系统 ==='); const response = await fetch(`${BASE_URL}/login/test`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(TEST_CREDENTIALS) }); const result = await response.json(); if (result.code === 200) { authToken = result.token; console.log('✅ 登录成功,获取到token'); return true; } else { console.error('❌ 登录失败:', result.msg); return false; } } /** * 模拟导入场景(不实际上传文件,直接构造数据) */ function simulateImportSuccess() { console.log('\n=== 步骤2: 模拟导入成功场景 ==='); // 模拟后端返回的状态数据 const mockSuccessResult = { taskId: 'task_' + Date.now(), status: 'SUCCESS', totalCount: 100, successCount: 100, failureCount: 0, progress: 100, message: '导入完成' }; console.log('模拟数据:', mockSuccessResult); // 模拟前端保存到localStorage const taskData = { taskId: mockSuccessResult.taskId, status: mockSuccessResult.status, hasFailures: mockSuccessResult.failureCount > 0, totalCount: mockSuccessResult.totalCount, successCount: mockSuccessResult.successCount, failureCount: mockSuccessResult.failureCount, saveTime: Date.now() }; localStorage.setItem('employee_import_last_task', JSON.stringify(taskData)); console.log('✅ 已保存导入任务到localStorage'); console.log('保存的数据:', JSON.stringify(taskData, null, 2)); return mockSuccessResult; } /** * 模拟导入部分失败场景 */ function simulateImportWithFailures() { console.log('\n=== 步骤3: 模拟导入部分失败场景 ==='); // 模拟后端返回的状态数据 const mockFailureResult = { taskId: 'task_' + Date.now(), status: 'SUCCESS', totalCount: 100, successCount: 95, failureCount: 5, progress: 100, message: '导入完成' }; console.log('模拟数据:', mockFailureResult); // 模拟前端保存到localStorage const taskData = { taskId: mockFailureResult.taskId, status: mockFailureResult.status, hasFailures: mockFailureResult.failureCount > 0, totalCount: mockFailureResult.totalCount, successCount: mockFailureResult.successCount, failureCount: mockFailureResult.failureCount, saveTime: Date.now() }; localStorage.setItem('employee_import_last_task', JSON.stringify(taskData)); console.log('✅ 已保存导入任务到localStorage(包含失败记录)'); console.log('保存的数据:', JSON.stringify(taskData, null, 2)); return mockFailureResult; } /** * 验证localStorage中的数据 */ function verifyStorageData() { console.log('\n=== 步骤4: 验证localStorage数据 ==='); try { const data = localStorage.getItem('employee_import_last_task'); if (!data) { console.log('❌ localStorage中没有找到导入任务数据'); return null; } const task = JSON.parse(data); console.log('✅ 成功读取localStorage中的数据'); console.log('读取的数据:', JSON.stringify(task, null, 2)); // 验证必要字段 const requiredFields = ['taskId', 'status', 'hasFailures', 'totalCount', 'successCount', 'failureCount', 'saveTime']; const missingFields = requiredFields.filter(field => !(field in task)); if (missingFields.length > 0) { console.error('❌ 缺少必要字段:', missingFields); return null; } console.log('✅ 所有必要字段都存在'); // 验证字段类型 if (typeof task.taskId !== 'string') { console.error('❌ taskId字段类型错误,期望string,实际:', typeof task.taskId); return null; } if (typeof task.status !== 'string') { console.error('❌ status字段类型错误,期望string,实际:', typeof task.status); return null; } if (typeof task.hasFailures !== 'boolean') { console.error('❌ hasFailures字段类型错误,期望boolean,实际:', typeof task.hasFailures); return null; } if (typeof task.saveTime !== 'number') { console.error('❌ saveTime字段类型错误,期望number,实际:', typeof task.saveTime); return null; } console.log('✅ 所有字段类型正确'); // 验证时间戳合理性 const now = Date.now(); const timeDiff = now - task.saveTime; if (timeDiff < 0 || timeDiff > 60000) { // 超过1分钟认为不合理 console.warn('⚠️ saveTime时间戳可能异常,当前时间:', now, 'saveTime:', task.saveTime); } else { console.log('✅ saveTime时间戳正常'); } return task; } catch (error) { console.error('❌ 解析localStorage数据失败:', error); return null; } } /** * 测试状态恢复逻辑 */ function testRestoreState() { console.log('\n=== 步骤5: 测试状态恢复逻辑 ==='); const task = verifyStorageData(); if (!task) { console.log('❌ 无法恢复状态:localStorage数据无效'); return false; } // 模拟restoreImportState()方法的逻辑 const restoredState = { showFailureButton: false, currentTaskId: null }; if (task.hasFailures && task.taskId) { restoredState.currentTaskId = task.taskId; restoredState.showFailureButton = true; console.log('✅ 检测到失败记录,应该显示"查看导入失败记录"按钮'); console.log(' - showFailureButton:', restoredState.showFailureButton); console.log(' - currentTaskId:', restoredState.currentTaskId); } else { console.log('✅ 没有失败记录,不显示按钮'); console.log(' - showFailureButton:', restoredState.showFailureButton); console.log(' - currentTaskId:', restoredState.currentTaskId); } return restoredState; } /** * 测试过期数据处理 */ function testExpiredData() { console.log('\n=== 步骤6: 测试过期数据处理 ==='); // 创建一个8天前的过期数据 const eightDaysAgo = Date.now() - (8 * 24 * 60 * 60 * 1000); const expiredTask = { taskId: 'expired_task', status: 'SUCCESS', hasFailures: true, totalCount: 100, successCount: 90, failureCount: 10, saveTime: eightDaysAgo }; localStorage.setItem('employee_import_last_task', JSON.stringify(expiredTask)); console.log('已创建过期数据(8天前)'); // 模拟getImportTaskFromStorage()的过期检查逻辑 const sevenDays = 7 * 24 * 60 * 60 * 1000; const isExpired = Date.now() - expiredTask.saveTime > sevenDays; if (isExpired) { localStorage.removeItem('employee_import_last_task'); console.log('✅ 检测到过期数据,已清除'); return true; } else { console.log('❌ 过期检查逻辑异常'); return false; } } /** * 测试清除导入历史功能 */ function testClearHistory() { console.log('\n=== 步骤7: 测试清除导入历史功能 ==='); // 先保存一些测试数据 const testTask = { taskId: 'test_clear_task', status: 'SUCCESS', hasFailures: true, totalCount: 50, successCount: 45, failureCount: 5, saveTime: Date.now() }; localStorage.setItem('employee_import_last_task', JSON.stringify(testTask)); console.log('已创建测试数据'); // 模拟clearImportHistory()方法 localStorage.removeItem('employee_import_last_task'); console.log('✅ 已清除导入历史'); // 验证是否真的清除了 const data = localStorage.getItem('employee_import_last_task'); if (data === null) { console.log('✅ 验证成功:导入历史已完全清除'); return true; } else { console.error('❌ 清除失败:localStorage中仍有数据'); return false; } } /** * 测试字段名一致性 */ function testFieldConsistency() { console.log('\n=== 步骤8: 测试字段名一致性 ==='); // 模拟ImportStatusVO返回的数据(后端) const backendData = { taskId: 'task_test', status: 'SUCCESS', totalCount: 100, successCount: 95, failureCount: 5, progress: 100 }; console.log('后端返回的数据:', backendData); // 模拟saveImportTaskToStorage()调用的数据(前端) const frontendSaveData = { taskId: backendData.taskId, status: backendData.status, hasFailures: backendData.failureCount > 0, totalCount: backendData.totalCount, successCount: backendData.successCount, failureCount: backendData.failureCount }; console.log('前端保存的数据:', frontendSaveData); // 验证字段映射 const fieldMappings = [ { backend: 'taskId', frontend: 'taskId' }, { backend: 'status', frontend: 'status' }, { backend: 'totalCount', frontend: 'totalCount' }, { backend: 'successCount', frontend: 'successCount' }, { backend: 'failureCount', frontend: 'failureCount' } ]; let allMatch = true; fieldMappings.forEach(mapping => { const backendValue = backendData[mapping.backend]; const frontendValue = frontendSaveData[mapping.frontend]; if (backendValue === frontendValue) { console.log(`✅ ${mapping.backend} → ${mapping.frontend}: 值一致 (${backendValue})`); } else { console.error(`❌ ${mapping.backend} → ${mapping.frontend}: 值不一致`); allMatch = false; } }); // 验证saveTime字段 if (frontendSaveData.saveTime || typeof frontendSaveData.saveTime === 'number') { console.log('✅ saveTime字段存在且为number类型'); } else { console.error('❌ saveTime字段缺失或类型错误'); allMatch = false; } return allMatch; } /** * 运行所有测试 */ async function runAllTests() { console.log('╔════════════════════════════════════════════════════════════╗'); console.log('║ 员工导入状态持久化功能 - 完整测试套件 ║'); console.log('╚════════════════════════════════════════════════════════════╝'); // 清理环境 localStorage.removeItem('employee_import_last_task'); console.log('✅ 测试环境已清理'); // 登录 const loginSuccess = await login(); if (!loginSuccess) { console.error('\n❌ 测试终止:登录失败'); return; } const results = { login: true, importSuccess: false, importWithFailures: false, verifyStorage: false, restoreState: false, expiredData: false, clearHistory: false, fieldConsistency: false }; // 测试1: 导入成功场景 try { simulateImportSuccess(); const task = verifyStorageData(); results.importSuccess = (task !== null && !task.hasFailures); } catch (error) { console.error('❌ 导入成功场景测试失败:', error); } // 测试2: 导入部分失败场景 try { localStorage.removeItem('employee_import_last_task'); // 清理 simulateImportWithFailures(); const task = verifyStorageData(); results.importWithFailures = (task !== null && task.hasFailures); } catch (error) { console.error('❌ 导入部分失败场景测试失败:', error); } // 测试3: 状态恢复 try { const state = testRestoreState(); results.restoreState = (state !== false && state.showFailureButton === true); } catch (error) { console.error('❌ 状态恢复测试失败:', error); } // 测试4: 过期数据处理 try { localStorage.removeItem('employee_import_last_task'); // 清理 results.expiredData = testExpiredData(); } catch (error) { console.error('❌ 过期数据处理测试失败:', error); } // 测试5: 清除导入历史 try { results.clearHistory = testClearHistory(); } catch (error) { console.error('❌ 清除导入历史测试失败:', error); } // 测试6: 字段名一致性 try { results.fieldConsistency = testFieldConsistency(); } catch (error) { console.error('❌ 字段名一致性测试失败:', error); } // 输出测试报告 console.log('\n╔════════════════════════════════════════════════════════════╗'); console.log('║ 测试结果汇总 ║'); console.log('╚════════════════════════════════════════════════════════════╝\n'); const testNames = { login: '用户登录', importSuccess: '导入成功场景', importWithFailures: '导入部分失败场景', restoreState: '状态恢复逻辑', expiredData: '过期数据处理', clearHistory: '清除导入历史', fieldConsistency: '字段名一致性' }; let passCount = 0; let failCount = 0; Object.keys(results).forEach(key => { const status = results[key] ? '✅ PASS' : '❌ FAIL'; const testName = testNames[key] || key; console.log(`${status} - ${testName}`); if (results[key]) { passCount++; } else { failCount++; } }); console.log('\n--------------------------------------------------------'); console.log(`总计: ${passCount + failCount} 个测试`); console.log(`通过: ${passCount} 个`); console.log(`失败: ${failCount} 个`); console.log('--------------------------------------------------------\n'); if (failCount === 0) { console.log('🎉 所有测试通过!导入状态持久化功能正常工作。'); } else { console.log('⚠️ 部分测试失败,请检查相关功能。'); } // 清理测试数据 localStorage.removeItem('employee_import_last_task'); console.log('✅ 测试数据已清理\n'); } // 运行测试 runAllTests().catch(error => { console.error('❌ 测试执行异常:', error); process.exit(1); });