71 lines
3.8 KiB
JavaScript
71 lines
3.8 KiB
JavaScript
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')
|
||
|
|
})
|