Files
hera-web/scripts/avatarEntry.test.cjs
T

71 lines
3.8 KiB
JavaScript
Raw Normal View History

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')
const profile = { nickname: '测试', gender: '男', birthday: '1998-06-18', birthdayCalendar: 'solar', birthHour: '辰时', province: '北京市', city: '北京市', district: '朝阳区', remainingEdits: 5 }
function render(env, sheet = false) {
const exports = {}, updates = [], media = []
let index = 0
const source = fs.readFileSync(path.join(__dirname, '../src/pages/profile-edit/index.tsx'), 'utf8')
vm.runInNewContext(ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS,
target: ts.ScriptTarget.ES2019, jsx: ts.JsxEmit.ReactJSX } }).outputText, {
exports, process: { env: { TARO_ENV: env } }, require: id => {
if (id === 'react/jsx-runtime') return require(id)
if (id === 'react') return { useEffect: () => {}, useRef: initial => ({ current: initial }), useState: initial => {
const current = index++
let value = typeof initial === 'function' ? initial() : initial
if (value === null || (value && typeof value === 'object' && 'nickname' in value)) value = profile
if (initial === true) value = false
if (current === 5) value = sheet // avatarSheetOpen
return [value, next => updates.push([current, next])]
} }
if (id === '@tarojs/taro') return { useRouter: () => ({ params: {} }), default: {
chooseMedia: async options => { media.push(options); return { tempFiles: [{ tempFilePath: 'temp:album', size: 10 }] } }, showToast: () => {}
} }
if (id === '@tarojs/components') return { View: 'View', Text: 'Text', Button: 'Button', Input: 'Input', Picker: 'Picker' }
if (id === 'china-area-data') return { default: {} }
if (id.endsWith('/NavBar')) return { NavBar: 'NavBar' }
if (id.endsWith('/UserAvatar')) return { UserAvatar: 'UserAvatar' }
if (id.endsWith('/BirthdayPicker')) return { BirthdayPicker: 'BirthdayPicker' }
if (id.endsWith('/frontendPreview')) return { isFrontendPreview: () => false }
if (id.endsWith('/avatarDemo')) return { isAvatarDemo: () => false }
return {}
}
})
const collect = node => {
if (!node || typeof node !== 'object') return []
if (Array.isArray(node)) return node.flatMap(collect)
return [node, ...collect(node.props?.children)]
}
return { nodes: collect(exports.default()), updates, media }
}
test('微信端头像本身直接绑定官方chooseAvatar,不再弹自定义菜单', () => {
const h = render('weapp', true)
const button = h.nodes.find(node => node.props?.className === 'avatar-button')
assert.equal(button.props.openType, 'chooseAvatar')
assert.equal(button.props.onClick, undefined)
assert.equal(typeof button.props.onChooseAvatar, 'function')
assert.ok(!h.nodes.some(node => node.props?.className === 'avatar-mask'))
button.props.onChooseAvatar({ detail: { avatarUrl: 'temp:wechat-avatar' } })
assert.equal(h.media.length, 0)
assert.ok(h.updates.some(([, value]) => value === 'temp:wechat-avatar'))
assert.ok(h.updates.some(([index, value]) => index === 5 && value === false))
})
test('H5保留相册拍照菜单,不伪造微信官方头像选择能力', async () => {
const h = render('h5')
const button = h.nodes.find(node => node.props?.className === 'avatar-button')
assert.equal(button.props.openType, undefined)
assert.equal(button.props.onChooseAvatar, undefined)
button.props.onClick()
assert.ok(h.updates.some(([index, value]) => index === 5 && value === true))
const opened = render('h5', true)
const album = opened.nodes.find(node => node.props?.children === '从相册选择')
await album.props.onClick()
assert.equal(opened.media.length, 1)
assert.equal(opened.media[0].sourceType[0], 'album')
})