Files
Genarrative/scripts/check-wechat-miniprogram-auth-smoke.mjs

115 lines
3.1 KiB
JavaScript

import { spawnSync } from 'node:child_process';
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
const repoRoot = process.cwd();
const failures = [];
const smokeSteps = [
{
label: '小程序壳请求与 hash 回跳静态检查',
run: checkMiniProgramShell,
},
{
label: 'api-server 小程序登录与会话来源测试',
run: () =>
runCommand('cargo', [
'test',
'-p',
'api-server',
'wechat_miniprogram_login_returns_system_token_and_marks_session_source',
'--manifest-path',
'server-rs/Cargo.toml',
'--',
'--nocapture',
]),
},
{
label: 'H5 auth hash 消费测试',
run: () =>
runCommand(process.execPath, [
fileURLToPath(new URL('../node_modules/vitest/vitest.mjs', import.meta.url)),
'run',
'src/services/authService.test.ts',
'-t',
'consumes auth callback hash and persists the returned access token',
]),
},
];
for (const step of smokeSteps) {
console.log(`[wechat-miniprogram-auth-smoke] ${step.label}`);
step.run();
}
if (failures.length > 0) {
console.error('\n[wechat-miniprogram-auth-smoke] 未通过:');
for (const failure of failures) {
console.error(`- ${failure}`);
}
process.exit(1);
}
console.log('\n[wechat-miniprogram-auth-smoke] 通过');
function checkMiniProgramShell() {
const shellPath = join(repoRoot, 'miniprogram', 'pages', 'web-view', 'index.js');
const authServiceTestPath = join(repoRoot, 'src', 'services', 'authService.test.ts');
ensureNeedles(shellPath, [
'/api/auth/wechat/miniprogram-login',
"'x-client-type': MINI_PROGRAM_CLIENT_TYPE",
"'x-client-runtime': MINI_PROGRAM_CLIENT_RUNTIME",
'auth_provider',
'auth_token',
'auth_binding_status',
'bindingStatus',
]);
// 中文注释:这里锁定 H5 消费回跳 hash 的真实测试输入,避免只检查实现文本。
ensureNeedles(authServiceTestPath, [
'#auth_provider=wechat&auth_token=jwt-callback-token&auth_binding_status=pending_bind_phone',
'consumeAuthCallbackResult()',
"bindingStatus: 'pending_bind_phone'",
"expect(getStoredAccessToken()).toBe('jwt-callback-token')",
]);
}
function ensureNeedles(relativeOrFullPath, needles) {
if (!existsSync(relativeOrFullPath)) {
failures.push(`缺少文件:${relativeOrFullPath}`);
return;
}
const content = readFileSync(relativeOrFullPath, 'utf8');
for (const needle of needles) {
if (!content.includes(needle)) {
failures.push(`${relativeOrFullPath} 缺少内容:${needle}`);
}
}
}
function runCommand(command, args) {
const result = spawnSync(command, args, {
cwd: repoRoot,
env: process.env,
shell: false,
stdio: 'inherit',
});
if (result.error) {
failures.push(`${command} 启动失败:${result.error.message}`);
return;
}
if (result.signal) {
failures.push(`${command} 被信号终止:${result.signal}`);
return;
}
if ((result.status ?? 0) !== 0) {
failures.push(`${command} ${args.join(' ')} 退出码 ${result.status}`);
}
}