466 lines
13 KiB
JavaScript
466 lines
13 KiB
JavaScript
|
|
/**
|
|||
|
|
* 中介黑名单弹窗优化功能测试脚本
|
|||
|
|
*
|
|||
|
|
* 测试目标:
|
|||
|
|
* 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 };
|