2026-10-15 21:56:45 +08:00
|
|
|
const test = require('node:test')
|
|
|
|
|
const assert = require('node:assert/strict')
|
|
|
|
|
const fs = require('node:fs')
|
|
|
|
|
const path = require('node:path')
|
|
|
|
|
const vm = require('node:vm')
|
|
|
|
|
const ts = require('typescript')
|
|
|
|
|
|
2026-10-17 22:44:09 +08:00
|
|
|
function loadApi(env, search, initialToken = 'test-token') {
|
2026-10-15 21:56:45 +08:00
|
|
|
let requests = 0
|
|
|
|
|
let uploads = 0
|
2026-10-17 22:44:09 +08:00
|
|
|
let token = initialToken
|
|
|
|
|
let serverProfile = { id: 9, nickname: 'Original', birthday: '1998-06-18' }
|
2026-10-15 21:56:45 +08:00
|
|
|
const taro = { default: {
|
2026-10-17 22:44:09 +08:00
|
|
|
getStorageSync: () => token,
|
|
|
|
|
setStorageSync: (key, value) => { if (key === 'token') token = value },
|
|
|
|
|
removeStorageSync: () => { token = '' },
|
|
|
|
|
request: async (options) => {
|
|
|
|
|
requests++
|
|
|
|
|
if (options.method === 'PUT') serverProfile = { ...serverProfile, ...options.data }
|
|
|
|
|
return { statusCode: 200, data: { code: 0, data: { ...serverProfile } } }
|
|
|
|
|
},
|
|
|
|
|
uploadFile: async () => { uploads++; return { statusCode: 200, data: JSON.stringify({ code: 0, data: { id: 9 } }) } }
|
2026-10-15 21:56:45 +08:00
|
|
|
} }
|
|
|
|
|
const cache = {}
|
|
|
|
|
function load(name) {
|
|
|
|
|
if (cache[name]) return cache[name]
|
2026-10-17 22:44:09 +08:00
|
|
|
const source = fs.readFileSync(path.resolve(__dirname, `../src/${name}.ts`), 'utf8')
|
2026-10-15 21:56:45 +08:00
|
|
|
const code = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2017 } }).outputText
|
|
|
|
|
const exports = {}
|
|
|
|
|
cache[name] = exports
|
|
|
|
|
vm.runInNewContext(code, {
|
|
|
|
|
exports, process: { env: { TARO_ENV: env } }, window: { location: { search } }, URLSearchParams,
|
2026-10-17 22:44:09 +08:00
|
|
|
require: (id) => id === '@tarojs/taro' ? taro : load(path.posix.normalize(path.posix.join(path.posix.dirname(name), id)))
|
2026-10-15 21:56:45 +08:00
|
|
|
})
|
|
|
|
|
return exports
|
|
|
|
|
}
|
2026-10-17 22:44:09 +08:00
|
|
|
return { api: load('services/request').api, getToken: () => token, counts: () => ({ requests, uploads }) }
|
2026-10-15 21:56:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
test('显式H5预览使用示例资料,阻止后端读取、保存和上传', async () => {
|
|
|
|
|
const { api, counts } = loadApi('h5', '?preview=1')
|
|
|
|
|
const profile = await api.profile()
|
|
|
|
|
assert.equal(profile.id, 0)
|
|
|
|
|
assert.equal(profile.birthday, '1998-06-18')
|
|
|
|
|
await assert.rejects(api.updateProfile({ nickname: 'Changed' }), /纯前端预览/)
|
|
|
|
|
await assert.rejects(api.uploadAvatar('local.png'), /纯前端预览/)
|
|
|
|
|
await assert.rejects(api.agreement('privacy'), /纯前端预览/)
|
|
|
|
|
assert.deepEqual(counts(), { requests: 0, uploads: 0 })
|
|
|
|
|
profile.nickname = 'Mutated'
|
|
|
|
|
assert.equal((await api.profile()).nickname, 'You')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('普通H5和微信端不使用预览资料', async () => {
|
|
|
|
|
for (const [env, search] of [['h5', ''], ['h5', '?preview=0'], ['weapp', '?preview=1']]) {
|
|
|
|
|
const { api, counts } = loadApi(env, search)
|
|
|
|
|
assert.equal((await api.profile()).id, 9)
|
|
|
|
|
assert.deepEqual(counts(), { requests: 1, uploads: 0 })
|
|
|
|
|
}
|
|
|
|
|
})
|
2026-10-17 22:44:09 +08:00
|
|
|
|
|
|
|
|
test('首页与我的复用资料,修改生日后立即读取新值,编辑页可强制刷新', async () => {
|
|
|
|
|
const { api, counts } = loadApi('h5', '')
|
|
|
|
|
await Promise.all([api.profile(), api.profile()])
|
|
|
|
|
assert.equal(counts().requests, 1)
|
|
|
|
|
await api.updateProfile({ birthday: '2000-02-05' })
|
|
|
|
|
const updated = await api.profile()
|
|
|
|
|
assert.equal(updated.birthday, '2000-02-05')
|
|
|
|
|
assert.equal(counts().requests, 2)
|
|
|
|
|
updated.birthday = '1900-01-01'
|
|
|
|
|
assert.equal((await api.profile()).birthday, '2000-02-05')
|
|
|
|
|
await api.profile(true)
|
|
|
|
|
assert.equal(counts().requests, 3)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('已登录头像演示无需token,保存同步且不注册、不上传真实后端,刷新重置', async () => {
|
|
|
|
|
const { api, counts, getToken } = loadApi('h5', '?avatarDemo=1', '')
|
|
|
|
|
assert.equal((await api.profile()).nickname, '演示用户')
|
|
|
|
|
assert.equal((await api.profile()).id, -1)
|
|
|
|
|
const uploaded = await api.uploadAvatar('blob:local-photo')
|
|
|
|
|
assert.equal(uploaded.avatarUrl, 'blob:local-photo')
|
|
|
|
|
assert.equal(uploaded.remainingEdits, 5)
|
|
|
|
|
assert.equal((await api.profile(true)).avatarUrl, 'blob:local-photo')
|
|
|
|
|
await api.updateProfile({ nickname: '我的演示' })
|
|
|
|
|
assert.equal((await api.profile()).nickname, '我的演示')
|
|
|
|
|
assert.equal((await api.profile()).remainingEdits, 4)
|
|
|
|
|
await assert.rejects(api.uploadAvatar('https://remote.example/photo.png'), /本地图片/)
|
|
|
|
|
await assert.rejects(api.wxLogin('fake'), /不请求真实后端/)
|
|
|
|
|
await assert.rejects(api.sendSms('13800000000'), /不请求真实后端/)
|
|
|
|
|
await assert.rejects(api.bindPhone('fake', '13800000000', '123456'), /不请求真实后端/)
|
|
|
|
|
assert.equal(getToken(), '')
|
|
|
|
|
assert.deepEqual(counts(), { requests: 0, uploads: 0 })
|
|
|
|
|
assert.equal((await loadApi('h5', '?avatarDemo=1').api.profile()).avatarUrl, '')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('头像演示不进入微信端;不影响原只读preview和真实token', async () => {
|
|
|
|
|
const real = loadApi('weapp', '?avatarDemo=1')
|
|
|
|
|
assert.equal((await real.api.profile()).id, 9)
|
|
|
|
|
assert.equal(real.counts().requests, 1)
|
|
|
|
|
const preview = loadApi('h5', '?preview=1&avatarDemo=1')
|
|
|
|
|
assert.equal((await preview.api.profile()).id, 0)
|
|
|
|
|
await assert.rejects(preview.api.uploadAvatar('blob:local'), /纯前端预览/)
|
|
|
|
|
const demo = loadApi('h5', '?avatarDemo=1')
|
|
|
|
|
await demo.api.uploadAvatar('blob:local')
|
|
|
|
|
assert.equal(demo.getToken(), 'test-token')
|
|
|
|
|
})
|