/** * 中介黑名单弹窗优化功能测试脚本 * * 测试目标: * 1. 新增模式下的类型选择卡片交互 * 2. 个人类型表单验证和提交 * 3. 机构类型表单验证和提交 * 4. 机构类型证件号与统一社会信用代码同步 * 5. 修改模式下的表单锁定和编辑 * * 运行环境:Node.js * 依赖:axios * * 使用方法: * node test_intermediary_dialog.js */ const axios = require('axios'); // 配置 const CONFIG = { baseURL: 'http://localhost:8080', testUser: { username: 'admin', password: 'admin123' } }; // 创建axios实例 const api = axios.create({ baseURL: CONFIG.baseURL, timeout: 10000, headers: { 'Content-Type': 'application/json' } }); // 存储测试数据 let authToken = null; let testIndivId = null; let testCorpId = null; // 颜色输出 const colors = { reset: '\x1b[0m', bright: '\x1b[1m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', cyan: '\x1b[36m' }; function log(message, color = 'reset') { console.log(`${colors[color]}${message}${colors.reset}`); } function logSection(title) { console.log('\n' + '='.repeat(60)); log(title, 'bright'); console.log('='.repeat(60)); } function logTest(name, passed, details = '') { const status = passed ? '✓ 通过' : '✗ 失败'; const color = passed ? 'green' : 'red'; log(`${status} - ${name}`, color); if (details) { log(` ${details}`, 'yellow'); } } // ==================== 测试用例 ==================== /** * 测试1:登录获取Token */ async function testLogin() { logSection('测试1:登录系统'); try { const response = await api.post('/login', { username: CONFIG.testUser.username, password: CONFIG.testUser.password }); if (response.data.code === 200) { authToken = response.data.token; api.defaults.headers.common['Authorization'] = `Bearer ${authToken}`; logTest('登录成功', true, `Token: ${authToken.substring(0, 20)}...`); return true; } else { logTest('登录失败', false, response.data.msg); return false; } } catch (error) { logTest('登录异常', false, error.message); return false; } } /** * 测试2:新增个人中介 - 验证必填字段 */ async function testAddIndividualRequired() { logSection('测试2:新增个人中介 - 验证必填字段'); const testCases = [ { name: '空姓名', data: { intermediaryType: '1', certificateNo: '123456789012345678' }, shouldFail: true }, { name: '空证件号', data: { intermediaryType: '1', name: '测试个人' }, shouldFail: true }, { name: '完整必填字段', data: { intermediaryType: '1', name: '张三', certificateNo: '123456789012345678' }, shouldFail: false } ]; for (const testCase of testCases) { try { const response = await api.post('/dpc/intermediary', testCase.data); const passed = testCase.shouldFail ? response.data.code !== 200 : response.data.code === 200; if (!testCase.shouldFail && response.data.code === 200) { testIndivId = response.data.data; // 假设返回ID } logTest(testCase.name, passed, testCase.shouldFail ? '应该被拒绝' : `成功创建,ID: ${response.data.data || 'N/A'}`); } catch (error) { logTest(testCase.name, testCase.shouldFail, `异常: ${error.response?.data?.msg || error.message}`); } } } /** * 测试3:新增个人中介 - 验证字段长度限制 */ async function testAddIndividualMaxLength() { logSection('测试3:新增个人中介 - 验证字段长度限制'); const testCases = [ { name: '姓名超过100字符', data: { intermediaryType: '1', name: 'A'.repeat(101), certificateNo: '123456789012345678' }, shouldFail: true }, { name: '证件号超过50字符', data: { intermediaryType: '1', name: '李四', certificateNo: 'B'.repeat(51) }, shouldFail: true }, { name: '备注超过500字符', data: { intermediaryType: '1', name: '王五', certificateNo: '123456789012345678', remark: 'R'.repeat(501) }, shouldFail: true } ]; for (const testCase of testCases) { try { const response = await api.post('/dpc/intermediary', testCase.data); const passed = response.data.code !== 200; logTest(testCase.name, passed, `响应: ${response.data.msg || 'N/A'}`); } catch (error) { logTest(testCase.name, true, `正确拒绝: ${error.response?.data?.msg || '字段验证失败'}`); } } } /** * 测试4:新增机构中介 - 验证证件号同步 */ async function testAddCorpSync() { logSection('测试4:新增机构中介 - 验证证件号同步'); const creditCode = '91110000123456789X'; const testData = { intermediaryType: '2', name: '测试机构有限公司', certificateNo: creditCode, // 这个值应该同步到 corpCreditCode corpType: '1', corpNature: '1' }; try { const response = await api.post('/dpc/intermediary', testData); if (response.data.code === 200) { testCorpId = response.data.data; logTest('机构创建成功', true, `证件号: ${creditCode}, ID: ${testCorpId}`); // 验证获取详情时证件号是否同步 const detailResponse = await api.get(`/dpc/intermediary/${testCorpId}`); if (detailResponse.data.code === 200) { const data = detailResponse.data.data; const synced = data.certificateNo === creditCode && data.corpCreditCode === creditCode; logTest('证件号同步验证', synced, `certificateNo: ${data.certificateNo}, corpCreditCode: ${data.corpCreditCode}`); } } else { logTest('机构创建失败', false, response.data.msg); } } catch (error) { logTest('机构创建异常', false, error.message); } } /** * 测试5:新增机构中介 - 验证统一社会信用代码长度 */ async function testAddCorpCreditCodeLength() { logSection('测试5:新增机构中介 - 验证统一社会信用代码长度'); const testCases = [ { name: '统一社会信用代码17位', data: { intermediaryType: '2', name: '测试机构A', certificateNo: '91110000123456789' }, shouldFail: false // 前端验证是18位,但后端可能接受 }, { name: '统一社会信用代码18位', data: { intermediaryType: '2', name: '测试机构B', certificateNo: '91110000123456789X' }, shouldFail: false }, { name: '统一社会信用代码19位', data: { intermediaryType: '2', name: '测试机构C', certificateNo: '91110000123456789XX' }, shouldFail: false // 前端会限制为18位 } ]; for (const testCase of testCases) { try { const response = await api.post('/dpc/intermediary', testCase.data); const length = testCase.data.certificateNo.length; logTest(`${testCase.name} (实际${length}位)`, response.data.code === 200, `响应: ${response.data.msg || '成功'}`); } catch (error) { logTest(testCase.name, false, `异常: ${error.response?.data?.msg || error.message}`); } } } /** * 测试6:修改个人中介 - 验证类型锁定 */ async function testEditIndividualTypeLock() { logSection('测试6:修改个人中介 - 验证类型锁定'); if (!testIndivId) { logTest('跳过测试', false, '没有可用的个人中介ID'); return; } try { // 获取详情 const getResponse = await api.get(`/dpc/intermediary/${testIndivId}`); if (getResponse.data.code === 200) { const originalData = getResponse.data.data; logTest('获取个人中介详情', true, `类型: ${originalData.intermediaryType}, 姓名: ${originalData.name}`); // 尝试修改(保持类型不变) const updateData = { ...originalData, name: '张三(已修改)', indivPhone: '13800138000' }; const updateResponse = await api.put('/dpc/intermediary', updateData); logTest('修改个人中介成功', updateResponse.data.code === 200, `新姓名: ${updateData.name}`); } } catch (error) { logTest('修改个人中介失败', false, error.message); } } /** * 测试7:修改机构中介 - 验证类型锁定 */ async function testEditCorpTypeLock() { logSection('测试7:修改机构中介 - 验证类型锁定'); if (!testCorpId) { logTest('跳过测试', false, '没有可用的机构中介ID'); return; } try { // 获取详情 const getResponse = await api.get(`/dpc/intermediary/${testCorpId}`); if (getResponse.data.code === 200) { const originalData = getResponse.data.data; logTest('获取机构中介详情', true, `类型: ${originalData.intermediaryType}, 名称: ${originalData.name}`); // 尝试修改(保持类型不变) const updateData = { ...originalData, name: '测试机构有限公司(已修改)', corpLegalRep: '法人代表' }; const updateResponse = await api.put('/dpc/intermediary', updateData); logTest('修改机构中介成功', updateResponse.data.code === 200, `新名称: ${updateData.name}`); } } catch (error) { logTest('修改机构中介失败', false, error.message); } } /** * 测试8:验证新增模式下未选择类型无法提交 */ async function testAddWithoutType() { logSection('测试8:验证新增模式下未选择类型无法提交'); // 这个测试主要验证前端行为,后端应该会拒绝没有类型的请求 const testData = { name: '无类型测试' // 没有 intermediaryType }; try { const response = await api.post('/dpc/intermediary', testData); const passed = response.data.code !== 200; logTest('后端拒绝无类型请求', passed, `响应: ${response.data.msg || '验证失败'}`); } catch (error) { logTest('后端正确拒绝', true, `异常: ${error.response?.data?.msg || '类型验证失败'}`); } } /** * 测试9:查询列表验证数据正确性 */ async function testListQuery() { logSection('测试9:查询列表验证数据正确性'); try { const response = await api.get('/dpc/intermediary/list', { params: { pageNum: 1, pageSize: 10 } }); if (response.data.code === 200) { const list = response.data.rows; logTest('查询列表成功', true, `共 ${response.data.total} 条记录`); // 统计类型分布 const indivCount = list.filter(item => item.intermediaryType === '1').length; const corpCount = list.filter(item => item.intermediaryType === '2').length; log(` 个人类型: ${indivCount} 条`, 'cyan'); log(` 机构类型: ${corpCount} 条`, 'cyan'); } else { logTest('查询列表失败', false, response.data.msg); } } catch (error) { logTest('查询列表异常', false, error.message); } } /** * 清理测试数据 */ async function cleanup() { logSection('清理测试数据'); const idsToDelete = []; if (testIndivId) idsToDelete.push(testIndivId); if (testCorpId) idsToDelete.push(testCorpId); for (const id of idsToDelete) { try { await api.delete(`/dpc/intermediary/${id}`); logTest(`删除测试数据 ID: ${id}`, true); } catch (error) { logTest(`删除失败 ID: ${id}`, false, error.message); } } } // ==================== 主流程 ==================== async function runTests() { log('\n╔════════════════════════════════════════════════════════════╗'); log('║ 中介黑名单弹窗优化功能测试 ║', 'bright'); log('║ 测试日期: ' + new Date().toLocaleString('zh-CN') + ' ║'); log('╚════════════════════════════════════════════════════════════╝'); try { // 按顺序执行测试 await testLogin(); await testAddIndividualRequired(); await testAddIndividualMaxLength(); await testAddCorpSync(); await testAddCorpCreditCodeLength(); await testEditIndividualTypeLock(); await testEditCorpTypeLock(); await testAddWithoutType(); await testListQuery(); logSection('测试完成'); log('所有测试用例执行完毕!', 'green'); } catch (error) { log('\n测试流程异常终止', 'red'); log(error.message, 'red'); } finally { // 询问是否清理测试数据 log('\n是否清理测试数据?(在自动化环境中会自动清理)', 'yellow'); await cleanup(); } } // 运行测试 if (require.main === module) { runTests().catch(console.error); } module.exports = {runTests};