Files
ccdi/doc/scripts/test_intermediary_dialog.js
2026-01-29 22:03:42 +08:00

466 lines
13 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 中介黑名单弹窗优化功能测试脚本
*
* 测试目标:
* 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 };