/** * Tool C Day 2 API测试脚本 * * 测试内容: * 1. 创建测试Excel文件 * 2. 上传文件创建Session * 3. 获取Session信息 * 4. 获取预览数据 * 5. 获取完整数据 * 6. 更新心跳 * 7. 删除Session * * 执行方式:node test-tool-c-day2.mjs */ import FormData from 'form-data'; import axios from 'axios'; import * as XLSX from 'xlsx'; import { Buffer } from 'buffer'; const BASE_URL = 'http://localhost:3000'; const API_PREFIX = '/api/v1/dc/tool-c'; // ==================== 辅助函数 ==================== function printSection(title) { console.log('\n' + '='.repeat(70)); console.log(` ${title}`); console.log('='.repeat(70) + '\n'); } function printSuccess(message) { console.log('✅ ' + message); } function printError(message) { console.log('❌ ' + message); } function printInfo(message) { console.log('ℹ️ ' + message); } // ==================== 创建测试Excel文件 ==================== function createTestExcelFile() { printSection('创建测试Excel文件'); // 创建医疗数据 const testData = [ { patient_id: 'P001', name: '张三', age: 25, gender: '男', diagnosis: '感冒', sbp: 120, dbp: 80 }, { patient_id: 'P002', name: '李四', age: 65, gender: '女', diagnosis: '高血压', sbp: 150, dbp: 95 }, { patient_id: 'P003', name: '王五', age: 45, gender: '男', diagnosis: '糖尿病', sbp: 135, dbp: 85 }, { patient_id: 'P004', name: '赵六', age: 70, gender: '女', diagnosis: '冠心病', sbp: 160, dbp: 100 }, { patient_id: 'P005', name: '钱七', age: 35, gender: '男', diagnosis: '胃炎', sbp: 110, dbp: 70 }, { patient_id: 'P006', name: '孙八', age: 55, gender: '女', diagnosis: '肺炎', sbp: 125, dbp: 82 }, { patient_id: 'P007', name: '周九', age: 48, gender: '男', diagnosis: '肝炎', sbp: 130, dbp: 88 }, { patient_id: 'P008', name: '吴十', age: 62, gender: '女', diagnosis: '关节炎', sbp: 145, dbp: 92 }, ]; // 创建工作簿 const ws = XLSX.utils.json_to_sheet(testData); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, 'Sheet1'); // 生成Buffer const excelBuffer = XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' }); printSuccess(`测试文件创建成功: ${testData.length}行 x ${Object.keys(testData[0]).length}列`); printInfo(`文件大小: ${(excelBuffer.length / 1024).toFixed(2)} KB`); return { buffer: excelBuffer, fileName: 'test-medical-data.xlsx', expectedRows: testData.length, expectedCols: Object.keys(testData[0]).length, }; } // ==================== API测试函数 ==================== async function testUploadFile(excelData) { printSection('测试1: 上传Excel文件创建Session'); try { const form = new FormData(); form.append('file', excelData.buffer, { filename: excelData.fileName, contentType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', }); printInfo(`上传文件: ${excelData.fileName}`); const response = await axios.post( `${BASE_URL}${API_PREFIX}/sessions/upload`, form, { headers: form.getHeaders(), timeout: 10000, } ); if (response.status === 201 && response.data.success) { printSuccess('文件上传成功'); console.log('响应数据:', JSON.stringify(response.data.data, null, 2)); const { sessionId, totalRows, totalCols, columns } = response.data.data; // 验证数据 if (totalRows === excelData.expectedRows && totalCols === excelData.expectedCols) { printSuccess(`数据验证通过: ${totalRows}行 x ${totalCols}列`); } else { printError(`数据不匹配: 预期${excelData.expectedRows}行x${excelData.expectedCols}列, 实际${totalRows}行x${totalCols}列`); } printInfo(`Session ID: ${sessionId}`); printInfo(`列名: ${columns.join(', ')}`); return sessionId; } else { printError('上传失败: ' + JSON.stringify(response.data)); return null; } } catch (error) { printError('上传异常: ' + (error.response?.data?.error || error.message)); if (error.response) { console.log('错误详情:', JSON.stringify(error.response.data, null, 2)); } return null; } } async function testGetSession(sessionId) { printSection('测试2: 获取Session信息'); try { printInfo(`Session ID: ${sessionId}`); const response = await axios.get( `${BASE_URL}${API_PREFIX}/sessions/${sessionId}`, { timeout: 5000 } ); if (response.status === 200 && response.data.success) { printSuccess('Session信息获取成功'); console.log('Session信息:', JSON.stringify(response.data.data, null, 2)); return true; } else { printError('获取失败'); return false; } } catch (error) { printError('获取异常: ' + (error.response?.data?.error || error.message)); return false; } } async function testGetPreviewData(sessionId) { printSection('测试3: 获取预览数据(前100行)'); try { printInfo(`Session ID: ${sessionId}`); const response = await axios.get( `${BASE_URL}${API_PREFIX}/sessions/${sessionId}/preview`, { timeout: 10000 } ); if (response.status === 200 && response.data.success) { printSuccess('预览数据获取成功'); const { totalRows, previewRows, previewData } = response.data.data; printInfo(`总行数: ${totalRows}, 预览行数: ${previewRows}`); printInfo(`预览数据前3行:`); console.log(JSON.stringify(previewData.slice(0, 3), null, 2)); return true; } else { printError('获取预览数据失败'); return false; } } catch (error) { printError('获取预览数据异常: ' + (error.response?.data?.error || error.message)); return false; } } async function testGetFullData(sessionId) { printSection('测试4: 获取完整数据'); try { printInfo(`Session ID: ${sessionId}`); const response = await axios.get( `${BASE_URL}${API_PREFIX}/sessions/${sessionId}/full`, { timeout: 10000 } ); if (response.status === 200 && response.data.success) { printSuccess('完整数据获取成功'); const { totalRows, data } = response.data.data; printInfo(`总行数: ${totalRows}`); printInfo(`完整数据前2行:`); console.log(JSON.stringify(data.slice(0, 2), null, 2)); return true; } else { printError('获取完整数据失败'); return false; } } catch (error) { printError('获取完整数据异常: ' + (error.response?.data?.error || error.message)); return false; } } async function testUpdateHeartbeat(sessionId) { printSection('测试5: 更新心跳'); try { printInfo(`Session ID: ${sessionId}`); const response = await axios.post( `${BASE_URL}${API_PREFIX}/sessions/${sessionId}/heartbeat`, {}, { timeout: 5000 } ); if (response.status === 200 && response.data.success) { printSuccess('心跳更新成功'); console.log('新过期时间:', response.data.data.expiresAt); return true; } else { printError('心跳更新失败'); return false; } } catch (error) { printError('心跳更新异常: ' + (error.response?.data?.error || error.message)); return false; } } async function testDeleteSession(sessionId) { printSection('测试6: 删除Session'); try { printInfo(`Session ID: ${sessionId}`); const response = await axios.delete( `${BASE_URL}${API_PREFIX}/sessions/${sessionId}`, { timeout: 5000 } ); if (response.status === 200 && response.data.success) { printSuccess('Session删除成功'); return true; } else { printError('Session删除失败'); return false; } } catch (error) { printError('Session删除异常: ' + (error.response?.data?.error || error.message)); return false; } } async function testGetDeletedSession(sessionId) { printSection('测试7: 验证Session已删除'); try { printInfo(`尝试获取已删除的Session: ${sessionId}`); const response = await axios.get( `${BASE_URL}${API_PREFIX}/sessions/${sessionId}`, { timeout: 5000 } ); printError('Session仍然存在(不应该)'); return false; } catch (error) { if (error.response?.status === 404) { printSuccess('Session已正确删除(返回404)'); return true; } else { printError('未预期的错误: ' + error.message); return false; } } } // ==================== 主测试函数 ==================== async function runAllTests() { console.log('\n' + '🚀'.repeat(35)); console.log(' Tool C Day 2 API测试'); console.log('🚀'.repeat(35)); const results = {}; try { // 创建测试文件 const excelData = createTestExcelFile(); // 测试1: 上传文件 const sessionId = await testUploadFile(excelData); results['上传文件'] = !!sessionId; if (!sessionId) { printError('上传失败,后续测试无法继续'); return results; } // 等待1秒 await new Promise(resolve => setTimeout(resolve, 1000)); // 测试2: 获取Session信息 results['获取Session'] = await testGetSession(sessionId); await new Promise(resolve => setTimeout(resolve, 500)); // 测试3: 获取预览数据 results['获取预览数据'] = await testGetPreviewData(sessionId); await new Promise(resolve => setTimeout(resolve, 500)); // 测试4: 获取完整数据 results['获取完整数据'] = await testGetFullData(sessionId); await new Promise(resolve => setTimeout(resolve, 500)); // 测试5: 更新心跳 results['更新心跳'] = await testUpdateHeartbeat(sessionId); await new Promise(resolve => setTimeout(resolve, 500)); // 测试6: 删除Session results['删除Session'] = await testDeleteSession(sessionId); await new Promise(resolve => setTimeout(resolve, 500)); // 测试7: 验证删除 results['验证删除'] = await testGetDeletedSession(sessionId); } catch (error) { printError('测试过程中发生异常: ' + error.message); console.error(error); } // 汇总结果 printSection('测试结果汇总'); let passed = 0; let total = 0; for (const [testName, result] of Object.entries(results)) { total++; if (result) { passed++; console.log(`${testName.padEnd(20)}: ✅ 通过`); } else { console.log(`${testName.padEnd(20)}: ❌ 失败`); } } console.log('\n' + '-'.repeat(70)); console.log(`总计: ${passed}/${total} 通过 (${((passed/total)*100).toFixed(1)}%)`); console.log('-'.repeat(70)); if (passed === total) { console.log('\n🎉 所有测试通过!Day 2 Session管理功能完成!\n'); } else { console.log(`\n⚠️ 有 ${total - passed} 个测试失败,请检查\n`); } } // 执行测试 runAllTests() .then(() => { console.log('测试完成'); process.exit(0); }) .catch((error) => { console.error('测试失败:', error); process.exit(1); });