/** * 门店登录 / 建店短信校验专项冒烟(需 API 已启动且 MOCK_SMS 开启) * 用法: node scripts/test-shop-auth.mjs */ import { resolveSmsCode, sendSmsWithCooldown } from './sms-test-helper.mjs'; const API = process.env.SMOKE_API ?? 'http://localhost:3000/api/v1'; async function req(clientApp, path, options = {}) { const headers = { 'Content-Type': 'application/json', 'X-Client-App': clientApp, ...(options.token ? { Authorization: `Bearer ${options.token}` } : {}), }; const res = await fetch(`${API}${path}`, { ...options, headers, body: options.body }); const json = await res.json(); if (json.code !== 0) throw new Error(`${path}: ${json.message}`); return json.data; } async function expectFail(clientApp, path, options = {}) { const headers = { 'Content-Type': 'application/json', 'X-Client-App': clientApp, ...(options.token ? { Authorization: `Bearer ${options.token}` } : {}), }; const res = await fetch(`${API}${path}`, { ...options, headers, body: options.body }); const json = await res.json(); if (json.code === 0) throw new Error(`${path}: expected failure`); return json.message; } async function main() { console.log('1. STORE_LOGIN unbound phone'); const unbound = await expectFail('SHOP_H5', '/shop/auth/sms/send', { method: 'POST', body: JSON.stringify({ phone: '13899999999', scene: 'STORE_LOGIN' }), }); if (!unbound.includes('未绑定门店')) throw new Error(`unexpected: ${unbound}`); console.log('2. STORE_LOGIN bound phone'); await sendSmsWithCooldown('SHOP_H5', '/shop/auth/sms/send', '13910000001', 'STORE_LOGIN'); const code = await resolveSmsCode('13910000001', 'STORE_LOGIN'); const login = await req('SHOP_H5', '/shop/auth/login/sms', { method: 'POST', body: JSON.stringify({ phone: '13910000001', code }), }); if (!login.accessToken || !login.refreshToken) throw new Error('login missing tokens'); console.log('3. Shop session me + refresh'); const me = await req('SHOP_H5', '/shop/auth/me', { token: login.accessToken }); if (me.phone !== '13910000001') throw new Error('me phone mismatch'); const refreshed = await req('SHOP_H5', '/shop/auth/token/refresh', { method: 'POST', body: JSON.stringify({ refreshToken: login.refreshToken }), }); if (!refreshed.accessToken) throw new Error('refresh failed'); console.log('4. Admin create store rejects occupied phone'); await sendSmsWithCooldown('HQ_WEB', '/admin/auth/sms/send', '13600000001', 'HQ_LOGIN'); const adminCode = await resolveSmsCode('13600000001', 'HQ_LOGIN'); const admin = await req('HQ_WEB', '/admin/auth/login/sms', { method: 'POST', body: JSON.stringify({ phone: '13600000001', code: adminCode }), }); const occupied = await expectFail('HQ_WEB', '/admin/stores', { method: 'POST', token: admin.accessToken, body: JSON.stringify({ partnerId: '1', cityId: '1', name: '重复手机号测试店', phone: '13910000001', district: '测试区', address: '测试地址1号', }), }); if (!occupied.includes('已绑定')) throw new Error(`unexpected: ${occupied}`); console.log('\n✅ shop-auth tests passed'); } main().catch((e) => { console.error(e); process.exit(1); });