Kaynağa Gözat

测试文件调整

liuchengsen 1 ay önce
ebeveyn
işleme
d20af83bf6

+ 146 - 101
zhijiayun-test/src/main/resources/static/invite-test.html

@@ -249,10 +249,9 @@
         <div class="module-tab" data-module="admin-license">5.入驻信息审核</div>
         <div class="module-tab" data-module="admin-license">5.入驻信息审核</div>
         <div class="module-tab" data-module="admin-payment">6.支付方案</div>
         <div class="module-tab" data-module="admin-payment">6.支付方案</div>
         <div class="module-tab" data-module="admin-anxin">7.安心付管理</div>
         <div class="module-tab" data-module="admin-anxin">7.安心付管理</div>
-        <div class="module-tab" data-module="admin-trial-quota">8.体验配额</div>
-        <div class="module-tab" data-module="admin-user">9.用户管理</div>
-        <div class="module-tab" data-module="admin-audit">10.审计日志</div>
-        <div class="module-tab" data-module="upload">11.文件上传</div>
+        <div class="module-tab" data-module="admin-user">8.用户管理</div>
+        <div class="module-tab" data-module="admin-audit">9.审计日志</div>
+        <div class="module-tab" data-module="upload">10.文件上传</div>
     </div>
     </div>
 
 
     <div id="panels"></div>
     <div id="panels"></div>
@@ -371,6 +370,26 @@ async function runTest(sectionId, method, path, body, requireAuth, validatorName
             .forEach(fid => { const el = document.getElementById(fid); if (el) el.value = anxinCardId; });
             .forEach(fid => { const el = document.getElementById(fid); if (el) el.value = anxinCardId; });
     }
     }
 
 
+    // 自动更新Token:登录/刷新Token/心跳等接口返回新accessToken时,回填到当前侧Token输入框
+    // 避免后续需认证测试使用过期Token而失败
+    const newAccessToken = result.data?.data?.accessToken;
+    if (newAccessToken) {
+        if (activeSide === 'admin') {
+            const adminTokenEl = document.getElementById('adminToken');
+            if (adminTokenEl) adminTokenEl.value = newAccessToken;
+        } else {
+            const tokenEl = document.getElementById('token');
+            if (tokenEl) tokenEl.value = newAccessToken;
+        }
+    }
+
+    // 自动回填refreshToken到刷新Token测试输入框(登录/心跳等接口返回refreshToken时)
+    const newRefreshToken = result.data?.data?.refreshToken;
+    if (newRefreshToken) {
+        const refreshEl = document.getElementById('auth-refresh-refreshToken');
+        if (refreshEl) refreshEl.value = newRefreshToken;
+    }
+
     if (channel === 'ALIPAY' && qrBase64) {
     if (channel === 'ALIPAY' && qrBase64) {
         // 支付宝:DeepSeek 风格自定义弹窗,展示二维码
         // 支付宝:DeepSeek 风格自定义弹窗,展示二维码
         showAlipayModal(qrBase64, amount, orderNo);
         showAlipayModal(qrBase64, amount, orderNo);
@@ -664,48 +683,60 @@ document.getElementById('adminModuleTabs').addEventListener('click', (e) => {
     renderModule(e.target.dataset.module);
     renderModule(e.target.dataset.module);
 });
 });
 
 
-// ===================== 渲染模块面板 =====================
+// ===================== 渲染模块面板(持久化:切换tab不丢失测试结果)=====================
+const renderedModules = new Set();
 function renderModule(module) {
 function renderModule(module) {
     const panels = document.getElementById('panels');
     const panels = document.getElementById('panels');
-    let html = '';
-    switch (module) {
-    // 用户侧模块
-    case 'auth': html = renderAuthModule(); break;
-    case 'crawler': html = renderCrawlerModule(); break;
-    case 'invite': html = renderInviteModule(); break;
-    case 'coupon': html = renderCouponModule(); break;
-    case 'membership': html = renderMembershipModule(); break;
-    case 'payment': html = renderPaymentModule(); break;
-    case 'watchlist': html = renderWatchlistModule(); break;
-    case 'trial-quota': html = renderTrialQuotaModule(); break;
-    case 'upload': html = renderUploadModule(); break;
-    case 'search': html = renderSearchModule(); break;
-    case 'platform-account': html = renderPlatformAccountModule(); break;
-    case 'business-license': html = renderBusinessLicenseModule(); break;
-    case 'platform-config': html = renderPlatformConfigModule(); break;
-    case 'search-record': html = renderSearchRecordModule(); break;
-    case 'platform-session': html = renderPlatformSessionModule(); break;
-    case 'content': html = renderContentModule(); break;
-    case 'procurement-ledger': html = renderProcurementLedgerModule(); break;
-    case 'purchase-intent': html = renderPurchaseIntentModule(); break;
-    // 运营侧模块
-    case 'admin-membership': html = renderAdminMembershipModule(); break;
-    case 'admin-invite': html = renderAdminInviteModule(); break;
-    case 'admin-crawler': html = renderAdminCrawlerModule(); break;
-    case 'admin-coupon': html = renderAdminCouponModule(); break;
-    case 'admin-license': html = renderAdminLicenseModule(); break;
-    case 'admin-payment': html = renderAdminPaymentModule(); break;
-    case 'admin-anxin': html = renderAdminAnxinModule(); break;
-    case 'admin-trial-quota': html = renderAdminTrialQuotaModule(); break;
-    case 'admin-user': html = renderAdminUserModule(); break;
-    case 'admin-audit': html = renderAdminAuditModule(); break;
+    // 隐藏所有已渲染的模块面板
+    panels.querySelectorAll('.module-panel').forEach(p => p.style.display = 'none');
+    // 若该模块尚未渲染过,则创建并插入
+    let panel = document.getElementById('panel-' + module);
+    if (!panel) {
+        let html = '';
+        switch (module) {
+        // 用户侧模块
+        case 'auth': html = renderAuthModule(); break;
+        case 'crawler': html = renderCrawlerModule(); break;
+        case 'invite': html = renderInviteModule(); break;
+        case 'coupon': html = renderCouponModule(); break;
+        case 'membership': html = renderMembershipModule(); break;
+        case 'payment': html = renderPaymentModule(); break;
+        case 'watchlist': html = renderWatchlistModule(); break;
+        case 'upload': html = renderUploadModule(); break;
+        case 'search': html = renderSearchModule(); break;
+        case 'platform-account': html = renderPlatformAccountModule(); break;
+        case 'business-license': html = renderBusinessLicenseModule(); break;
+        case 'platform-config': html = renderPlatformConfigModule(); break;
+        case 'search-record': html = renderSearchRecordModule(); break;
+        case 'platform-session': html = renderPlatformSessionModule(); break;
+        case 'content': html = renderContentModule(); break;
+        case 'procurement-ledger': html = renderProcurementLedgerModule(); break;
+        case 'purchase-intent': html = renderPurchaseIntentModule(); break;
+        // 运营侧模块
+        case 'admin-membership': html = renderAdminMembershipModule(); break;
+        case 'admin-invite': html = renderAdminInviteModule(); break;
+        case 'admin-crawler': html = renderAdminCrawlerModule(); break;
+        case 'admin-coupon': html = renderAdminCouponModule(); break;
+        case 'admin-license': html = renderAdminLicenseModule(); break;
+        case 'admin-payment': html = renderAdminPaymentModule(); break;
+        case 'admin-anxin': html = renderAdminAnxinModule(); break;
+        case 'admin-user': html = renderAdminUserModule(); break;
+        case 'admin-audit': html = renderAdminAuditModule(); break;
+        }
+        panel = document.createElement('div');
+        panel.id = 'panel-' + module;
+        panel.className = 'module-panel';
+        panel.innerHTML = html;
+        panels.appendChild(panel);
+        renderedModules.add(module);
+        // 修复含引号的默认值:从 data-raw 属性恢复正确的 input value
+        panel.querySelectorAll('input[data-raw]').forEach(input => {
+            input.value = input.getAttribute('data-raw');
+            input.removeAttribute('data-raw');
+        });
     }
     }
-    panels.innerHTML = html;
-    // 修复含引号的默认值:从 data-raw 属性恢复正确的 input value
-    panels.querySelectorAll('input[data-raw]').forEach(input => {
-        input.value = input.getAttribute('data-raw');
-        input.removeAttribute('data-raw');
-    });
+    // 显示当前模块面板
+    panel.style.display = '';
 }
 }
 
 
 function toValidatorName(id) {
 function toValidatorName(id) {
@@ -1507,16 +1538,6 @@ function renderWatchlistModule() {
     ${testSection('watchlist-stats', '关注统计', 'GET', 'get', '/api/watchlist/stats', '需认证', 'auth-required', null, true, null, '获取关注统计信息')}`;
     ${testSection('watchlist-stats', '关注统计', 'GET', 'get', '/api/watchlist/stats', '需认证', 'auth-required', null, true, null, '获取关注统计信息')}`;
 }
 }
 
 
-function renderTrialQuotaModule() {
-    return `
-    <div class="batch-buttons">
-        <button class="btn btn-warning btn-sm" onclick="runTrialQuotaTests()">运行全部体验配额测试</button>
-    </div>
-    ${testSection('trial-quota-active', '生效中的体验配额', 'GET', 'get', '/api/trial-quota/active', '公开', 'auth-public', null, true, 'trialQuotaConfig', '查询当前生效的体验配额配置')}`;
-}
-
-
-
 function renderPaymentModule() {
 function renderPaymentModule() {
     return `
     return `
     <div class="batch-buttons">
     <div class="batch-buttons">
@@ -1927,28 +1948,6 @@ function renderAdminAnxinModule() {
 
 
 
 
 
 
-function renderAdminTrialQuotaModule() {
-    return `
-    <div class="batch-buttons"><button class="btn btn-warning btn-sm" onclick="runAdminTrialQuotaTests()">运行全部体验配额测试</button></div>
-    ${testSection('admin-tq-active', '当前体验配置', 'GET', 'get', '/api/trial-quota/active', '公开', 'auth-public', null, true, 'trialQuota', '获取当前激活的体验配额配置')}
-    ${testSection('admin-tq-list', '所有配置', 'GET', 'get', '/api/admin/trial-quota/configs', '需认证', 'auth-required', null, true, 'trialQuota', '查询所有体验配额配置列表')}
-    ${testSection('admin-tq-create', '创建配置', 'POST', 'post', '/api/admin/trial-quota/config', '需认证', 'auth-required',
-        [{label:'配置名称(configName)', name:'configName', placeholder:'新用户默认体验', default:'测试体验配置'},
-         {label:'体验天数(trialDays)', name:'trialDays', placeholder:'15', default:'15'},
-         {label:'日查询限制(dailyQueryLimit)', name:'dailyQueryLimit', placeholder:'20', default:'20'},
-         {label:'月关注限制(monthlyWatchlistLimit)', name:'monthlyWatchlistLimit', placeholder:'199', default:'199'},
-         {label:'配置类型(configType)', name:'configType', placeholder:'DEFAULT', default:'DEFAULT'},
-         {label:'用户类型(applicableUserType)', name:'applicableUserType', placeholder:'NEW_USER', default:'NEW_USER'}], false, 'trialQuota', '创建新的体验配额配置')}
-    ${testSection('admin-tq-update', '更新配置', 'PUT', 'put', '/api/admin/trial-quota/config/{id}', '需认证', 'auth-required',
-        [{label:'配置ID(id)', name:'id', placeholder:'1', default:'1'},
-         {label:'配置名称(configName)', name:'configName', placeholder:'更新后名称', default:'更新后的体验配置'},
-         {label:'体验天数(trialDays)', name:'trialDays', placeholder:'30', default:'30'},
-         {label:'日查询限制(dailyQueryLimit)', name:'dailyQueryLimit', placeholder:'50', default:'50'},
-         {label:'月关注限制(monthlyWatchlistLimit)', name:'monthlyWatchlistLimit', placeholder:'199', default:'199'}], false, 'trialQuota', '更新指定体验配额配置')}
-    ${testSection('admin-tq-delete', '删除配置', 'DELETE', 'delete', '/api/admin/trial-quota/config/{id}', '需认证', 'auth-required',
-        [{label:'配置ID(id)', name:'id', placeholder:'1', default:'1'}], false, null, '删除指定体验配额配置')}`;
-}
-
 function renderAdminUserModule() {
 function renderAdminUserModule() {
     return `
     return `
     <div class="batch-buttons"><button class="btn btn-warning btn-sm" onclick="runAdminUserTests()">运行全部用户管理测试</button></div>
     <div class="batch-buttons"><button class="btn btn-warning btn-sm" onclick="runAdminUserTests()">运行全部用户管理测试</button></div>
@@ -1958,9 +1957,6 @@ function renderAdminUserModule() {
          {label:'手机号(phone)', name:'phone', placeholder:'138', default:''},
          {label:'手机号(phone)', name:'phone', placeholder:'138', default:''},
          {label:'昵称(nickname)', name:'nickname', placeholder:'测试', default:''}], true, null, '查询前端注册用户列表(仅USER角色)')}
          {label:'昵称(nickname)', name:'nickname', placeholder:'测试', default:''}], true, null, '查询前端注册用户列表(仅USER角色)')}
     ${testSection('admin-admins-list', '管理员列表', 'GET', 'get', '/api/admin/admins?page=1&size=10', '需认证', 'auth-required', null, true, null, '查询管理员列表(t_admin表)')}
     ${testSection('admin-admins-list', '管理员列表', 'GET', 'get', '/api/admin/admins?page=1&size=10', '需认证', 'auth-required', null, true, null, '查询管理员列表(t_admin表)')}
-    ${testSection('admin-user-role', '修改用户角色', 'PUT', 'put', '/api/admin/users/{userId}/role', '需认证', 'auth-required',
-        [{label:'用户ID(userId)', name:'userId', placeholder:'1', default:'1'},
-         {label:'目标角色(role)', name:'role', placeholder:'ADMIN/SUPER_ADMIN/USER', default:'ADMIN'}], false, null, '升级用户为管理员(写入t_admin)/ 降级管理员为用户(删除t_admin记录)')}
     ${testSection('admin-user-kick', '强制踢出用户', 'POST', 'post', '/api/admin/users/{userId}/kick', '需认证', 'auth-required',
     ${testSection('admin-user-kick', '强制踢出用户', 'POST', 'post', '/api/admin/users/{userId}/kick', '需认证', 'auth-required',
         [{label:'用户ID(userId)', name:'userId', placeholder:'1', default:'1'}], false, null, '强制踢出前端用户:递增tokenVersion+清空RefreshToken')}
         [{label:'用户ID(userId)', name:'userId', placeholder:'1', default:'1'}], false, null, '强制踢出前端用户:递增tokenVersion+清空RefreshToken')}
     ${testSection('admin-admin-kick', '强制踢出管理员', 'POST', 'post', '/api/admin/admins/{adminId}/kick', '需认证', 'auth-required',
     ${testSection('admin-admin-kick', '强制踢出管理员', 'POST', 'post', '/api/admin/admins/{adminId}/kick', '需认证', 'auth-required',
@@ -2011,8 +2007,8 @@ function getSectionsInModule(modulePrefix) {
     });
     });
 }
 }
 
 
-const USER_MODULES = ['auth','crawler','invite','coupon','membership','payment','upload','search','platform-account','business-license','platform-config','search-record','platform-session','watchlist','trial-quota','content','procurement-ledger','purchase-intent'];
-const ADMIN_MODULES = ['admin-membership','admin-invite','admin-crawler','admin-coupon','admin-license','admin-payment','admin-anxin','admin-trial-quota','admin-user','admin-audit','upload'];
+const USER_MODULES = ['auth','crawler','invite','coupon','membership','payment','upload','search','platform-account','business-license','platform-config','search-record','platform-session','watchlist','content','procurement-ledger','purchase-intent'];
+const ADMIN_MODULES = ['admin-membership','admin-invite','admin-crawler','admin-coupon','admin-license','admin-payment','admin-anxin','admin-user','admin-audit','upload'];
 
 
 function countTestsInCurrentPanel() {
 function countTestsInCurrentPanel() {
     return document.querySelectorAll('.test-section button[onclick*="runTest"]').length;
     return document.querySelectorAll('.test-section button[onclick*="runTest"]').length;
@@ -2043,37 +2039,87 @@ async function runBatchTests(modulePrefix) {
     }
     }
 }
 }
 
 
-async function runAllTests() {
-    resetStats();
-    // 先遍历用户侧模块
-    for (const m of USER_MODULES) {
-        const tab = document.querySelector(`#moduleTabs .module-tab[data-module="${m}"]`);
-        if (tab) tab.click();
-        await new Promise(r => setTimeout(r, 50));
-        stats.total += countTestsInCurrentPanel();
-    }
-    // 再遍历运营侧模块
-    for (const m of ADMIN_MODULES) {
-        const tab = document.querySelector(`#adminModuleTabs .module-tab[data-module="${m}"]`);
-        if (tab) tab.click();
-        await new Promise(r => setTimeout(r, 50));
-        stats.total += countTestsInCurrentPanel();
+// 按指定测试ID顺序执行批量测试(用于一键测试时控制破坏性操作顺序)
+async function runBatchTestsOrdered(testIds) {
+    // 将尚未运行过的测试计入total
+    for (const id of testIds) {
+        if (!stats.hasOwnProperty(id)) stats.total++;
     }
     }
+    stats.pending = Math.max(0, stats.total - stats.pass - stats.fail);
     document.getElementById('totalCount').textContent = stats.total;
     document.getElementById('totalCount').textContent = stats.total;
-    stats.pending = stats.total;
     document.getElementById('pendingCount').textContent = stats.pending;
     document.getElementById('pendingCount').textContent = stats.pending;
-    // 逐模块执行 - 用户侧
+    for (const id of testIds) {
+        const btn = document.querySelector(`button[onclick*="runTest('${id}'"]`);
+        if (btn) {
+            btn.click();
+            await new Promise(r => setTimeout(r, 600));
+        }
+    }
+}
+
+// 认证模块主流程测试顺序:登录类在前,只读查询类居中,刷新Token/心跳居后
+// 跳过破坏性操作(登出/设置密码/修改手机号/注册),确保主流程接口能正常返回数据
+const AUTH_TEST_ORDER = [
+    'auth-send', 'auth-smslogin', 'auth-pwdlogin',
+    'auth-wechat-url', 'auth-wechat-login', 'auth-wechat-callback',
+    'auth-userinfo', 'auth-user-me', 'auth-dashboard',
+    'auth-heartbeat', 'auth-refresh'
+];
+
+async function runAllTests() {
+    resetStats();
+    stopAlipayPolling();
+    closeAlipayModal();
+
+    // ===== 第一步:用户侧 - 先登录确保Token有效(直接调用API建立登录态,不触发测试统计和弹窗)=====
     switchSide('user');
     switchSide('user');
+    await new Promise(r => setTimeout(r, 100));
+    {
+        // 发送验证码
+        await api('POST', '/api/auth/sms/send', { phone: PHONE(), scene: 'login' }, false);
+        await new Promise(r => setTimeout(r, 500));
+        // 短信登录
+        const loginRes = await api('POST', '/api/auth/sms/login', { phone: PHONE(), code: SMS_CODE(), scene: 'login' }, false);
+        if (loginRes.data?.code === 200 && loginRes.data?.data?.accessToken) {
+            document.getElementById('token').value = loginRes.data.data.accessToken;
+            updateRoleBadge(loginRes.data.data.role);
+            // 回填refreshToken供后续刷新Token测试使用
+            if (loginRes.data.data.refreshToken) {
+                const refreshEl = document.getElementById('auth-refresh-refreshToken');
+                if (refreshEl) refreshEl.value = loginRes.data.data.refreshToken;
+            }
+        }
+    }
+
+    // ===== 第二步:逐模块执行用户侧测试(各模块自行统计测试数量,避免重复计数)=====
     for (const m of USER_MODULES) {
     for (const m of USER_MODULES) {
         try {
         try {
             const tab = document.querySelector(`#moduleTabs .module-tab[data-module="${m}"]`);
             const tab = document.querySelector(`#moduleTabs .module-tab[data-module="${m}"]`);
             if (tab) tab.click();
             if (tab) tab.click();
             await new Promise(r => setTimeout(r, 100));
             await new Promise(r => setTimeout(r, 100));
-            await runBatchTests(m);
+            if (m === 'auth') {
+                // 认证模块按主流程顺序执行:登录类→只读查询→刷新Token/心跳(跳过登出等破坏性操作)
+                await runBatchTestsOrdered(AUTH_TEST_ORDER);
+            } else {
+                await runBatchTests(m);
+            }
         } catch (e) { console.error('模块 ' + m + ' 测试出错:', e); }
         } catch (e) { console.error('模块 ' + m + ' 测试出错:', e); }
     }
     }
-    // 逐模块执行 - 运营侧
+
+    // ===== 第三步:运营侧 - 先管理员登录确保Token有效(直接调用API建立登录态,不触发测试统计和弹窗)=====
     switchSide('admin');
     switchSide('admin');
+    await new Promise(r => setTimeout(r, 100));
+    {
+        const adminUsername = document.getElementById('adminPwdUsername')?.value || 'admin';
+        const adminPassword = document.getElementById('adminPwdPassword')?.value || 'admin@123';
+        const adminLoginRes = await api('POST', '/api/admin/auth/login', { username: adminUsername, password: adminPassword }, false);
+        if (adminLoginRes.data?.code === 200 && adminLoginRes.data?.data?.accessToken) {
+            document.getElementById('adminToken').value = adminLoginRes.data.data.accessToken;
+            updateAdminRoleBadge(adminLoginRes.data.data.role);
+        }
+    }
+
+    // ===== 第四步:逐模块执行运营侧测试 =====
     for (const m of ADMIN_MODULES) {
     for (const m of ADMIN_MODULES) {
         try {
         try {
             const tab = document.querySelector(`#adminModuleTabs .module-tab[data-module="${m}"]`);
             const tab = document.querySelector(`#adminModuleTabs .module-tab[data-module="${m}"]`);
@@ -2106,6 +2152,7 @@ function clearAllResults() {
     closeAlipayModal();
     closeAlipayModal();
     document.querySelectorAll('.response-box').forEach(b => b.style.display = 'none');
     document.querySelectorAll('.response-box').forEach(b => b.style.display = 'none');
     document.querySelectorAll('.status-badge').forEach(b => { b.textContent = ''; b.className = 'status-badge'; });
     document.querySelectorAll('.status-badge').forEach(b => { b.textContent = ''; b.className = 'status-badge'; });
+    document.querySelectorAll('.response-content').forEach(b => b.textContent = '');
     resetStats();
     resetStats();
 }
 }
 
 
@@ -2188,7 +2235,6 @@ function runBusinessLicenseTests() { runBatchTests('bl'); }
 function runPlatformConfigTests() { runBatchTests('pc'); }
 function runPlatformConfigTests() { runBatchTests('pc'); }
 function runSearchRecordTests() { runBatchTests('sr'); }
 function runSearchRecordTests() { runBatchTests('sr'); }
 function runPlatformSessionTests() { runBatchTests('ps'); }function runWatchlistTests() { runBatchTests('watchlist'); }
 function runPlatformSessionTests() { runBatchTests('ps'); }function runWatchlistTests() { runBatchTests('watchlist'); }
-function runTrialQuotaTests() { runBatchTests('trial-quota'); }
 function runContentTests() { runBatchTests('content'); }
 function runContentTests() { runBatchTests('content'); }
 function runProcurementLedgerTests() { runBatchTests('pl'); }
 function runProcurementLedgerTests() { runBatchTests('pl'); }
 function runPurchaseIntentTests() { runBatchTests('pi'); }
 function runPurchaseIntentTests() { runBatchTests('pi'); }
@@ -2200,7 +2246,6 @@ function runAdminCouponTests() { runBatchTests('admin-coupon'); }
 function runAdminLicenseTests() { runBatchTests('admin-license'); }
 function runAdminLicenseTests() { runBatchTests('admin-license'); }
 function runAdminPaymentTests() { runBatchTests('admin-payment'); }
 function runAdminPaymentTests() { runBatchTests('admin-payment'); }
 function runAdminAnxinTests() { runBatchTests('admin-anxin'); }
 function runAdminAnxinTests() { runBatchTests('admin-anxin'); }
-function runAdminTrialQuotaTests() { runBatchTests('admin-tq'); }
 function runAdminUserTests() { runBatchTests('admin-user'); }
 function runAdminUserTests() { runBatchTests('admin-user'); }
 function runAdminAuditTests() { runBatchTests('admin-audit'); }
 function runAdminAuditTests() { runBatchTests('admin-audit'); }