Files

26 lines
1.8 KiB
JavaScript

// 部署后冒烟:node scripts/smoke.mjs <base-url> <username> <password>
const [base, user, pass] = process.argv.slice(2);
if (!base || !user || !pass) { console.error('用法: node scripts/smoke.mjs <base-url> <username> <password>'); process.exit(2); }
let fail = 0;
const ok = (cond, label, extra) => { console.log((cond ? ' ✓ ' : ' ✗ ') + label + (cond ? '' : ' | ' + JSON.stringify(extra).slice(0, 160))); if (!cond) fail++; };
const health = await fetch(base + '/health').then((r) => r.json()).catch((e) => ({ error: String(e) }));
ok(health?.data?.status === 'ok', '/health', health);
const login = await fetch(base + '/auth/login', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ username: user, password: pass }) }).then((r) => r.json()).catch((e) => ({ error: String(e) }));
ok(login?.ok === true, '登录', login);
const token = login?.data?.token;
if (!token) { console.error('登录失败,后续跳过'); process.exit(1); }
const me = await fetch(base + '/auth/me', { headers: { authorization: 'Bearer ' + token } }).then((r) => r.json());
ok(me?.data?.username === user, '/auth/me 用户名', me);
const fp = await fetch(base + '/api/footprint_list', { method: 'POST', headers: { 'content-type': 'application/json', authorization: 'Bearer ' + token }, body: JSON.stringify({ query: { page: 1, page_size: 1 } }) }).then((r) => r.json());
ok(fp?.ok === true, '/api/footprint_list(当前账号 ' + (fp?.data?.total ?? '?') + ' 条)', fp?.error);
const inv = await fetch(base + '/admin/invites', { headers: { authorization: 'Bearer ' + token } }).then((r) => r.json()).catch(() => null);
if (inv) ok(inv?.ok === true, '/admin/invites(管理员)', inv); else console.log(' - 非管理员,跳过 invites 检查');
console.log(fail ? '\n✗ 冒烟未通过' : '\n✓ 冒烟通过');
process.exit(fail ? 1 : 0);