- 将讲解编号置于标题上方并增强辨识度 - 编号详情返回后保留输入界面并清空原编号 - 增加页面栈丢失时恢复编号输入页的兜底逻辑 - 补充编号布局和返回流程回归测试 Made-with: Proma
200 lines
7.3 KiB
TypeScript
200 lines
7.3 KiB
TypeScript
// @vitest-environment happy-dom
|
|
|
|
import { mount } from '@vue/test-utils'
|
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
import ExplainHallSelect from '@/components/explain/ExplainHallSelect.vue'
|
|
|
|
const hostEnvironmentMocks = vi.hoisted(() => ({
|
|
embeddedInWechatMiniProgram: false
|
|
}))
|
|
|
|
vi.mock('@/utils/hostEnvironment', () => ({
|
|
isEmbeddedInWechatMiniProgram: () => hostEnvironmentMocks.embeddedInWechatMiniProgram
|
|
}))
|
|
|
|
afterEach(() => {
|
|
hostEnvironmentMocks.embeddedInWechatMiniProgram = false
|
|
})
|
|
|
|
describe('讲解展厅选择列表', () => {
|
|
it('微信嵌入态独立页面可强制显示 H5 返回入口,且不使用宿主导航布局', async () => {
|
|
hostEnvironmentMocks.embeddedInWechatMiniProgram = true
|
|
const wrapper = mount(ExplainHallSelect, {
|
|
props: {
|
|
forceInternalHeader: true
|
|
}
|
|
})
|
|
|
|
expect(wrapper.findAll('.explain-page-header')).toHaveLength(1)
|
|
expect(wrapper.findAll('.header-back')).toHaveLength(1)
|
|
expect(wrapper.classes()).not.toContain('host-navigation')
|
|
|
|
await wrapper.get('.header-back').trigger('tap')
|
|
expect(wrapper.emitted('back')).toEqual([[]])
|
|
})
|
|
|
|
it('微信嵌入态未强制时保留宿主导航布局,保护首页讲解 Tab', () => {
|
|
hostEnvironmentMocks.embeddedInWechatMiniProgram = true
|
|
const wrapper = mount(ExplainHallSelect)
|
|
|
|
expect(wrapper.find('.explain-page-header').exists()).toBe(false)
|
|
expect(wrapper.classes()).toContain('host-navigation')
|
|
})
|
|
|
|
it('展厅卡片只显示讲解对象数量,不暴露业务单元契约', async () => {
|
|
const wrapper = mount(ExplainHallSelect, {
|
|
props: {
|
|
stage: 'hall',
|
|
halls: [
|
|
{
|
|
id: 'hall-evolution',
|
|
name: '生命演化厅',
|
|
explainCount: 6,
|
|
guideStopCount: 6,
|
|
searchText: '生命演化厅'
|
|
}
|
|
]
|
|
}
|
|
})
|
|
|
|
const cards = wrapper.findAll('.hall-card')
|
|
expect(cards).toHaveLength(1)
|
|
expect(wrapper.text()).toContain('生命演化厅')
|
|
expect(wrapper.text()).not.toContain('6 个讲解对象')
|
|
expect(wrapper.text()).not.toContain('业务单元')
|
|
|
|
await cards[0]?.trigger('tap')
|
|
expect(wrapper.emitted('hallClick')).toEqual([['hall-evolution']])
|
|
})
|
|
|
|
it('展厅阶段可输入讲解编号并保留前导零', async () => {
|
|
const wrapper = mount(ExplainHallSelect, {
|
|
props: { stage: 'hall' }
|
|
})
|
|
|
|
expect(wrapper.get('.code-entry-title').text()).toBe('编号讲解')
|
|
expect(wrapper.get('.hall-section-title').text()).toBe('按展厅选择')
|
|
expect(wrapper.find('.code-entry-arrow').exists()).toBe(false)
|
|
|
|
await wrapper.get('.code-entry-button').trigger('tap')
|
|
expect(wrapper.get('.header-title').text()).toBe('编号讲解')
|
|
expect(wrapper.find('.code-entry-close').exists()).toBe(false)
|
|
expect(wrapper.get('.code-entry-sheet-title').text()).toBe('输入讲解编号')
|
|
expect(wrapper.findAll('.code-digit-cell')).toHaveLength(4)
|
|
expect(wrapper.text()).toContain('请输入展品标签上的四位编号')
|
|
|
|
await wrapper.get('.code-entry-native-input').trigger('input', { detail: { value: '02a' } })
|
|
expect(wrapper.get('.code-entry-action.primary').attributes('disabled')).toBeDefined()
|
|
await wrapper.get('.code-entry-native-input').trigger('confirm')
|
|
expect(wrapper.get('.code-entry-error').text()).toBe('请输入完整的 4 位讲解编号')
|
|
|
|
await wrapper.get('.code-entry-native-input').trigger('input', { detail: { value: '0231' } })
|
|
expect(wrapper.findAll('.code-digit-value').map((item) => item.text())).toEqual(['0', '2', '3', '1'])
|
|
await wrapper.get('.code-entry-action.primary').trigger('tap')
|
|
|
|
expect(wrapper.emitted('codeSubmit')).toEqual([['0231']])
|
|
expect(wrapper.find('.code-entry-sheet').exists()).toBe(true)
|
|
|
|
wrapper.vm.completeCodeEntry()
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.find('.code-entry-sheet').exists()).toBe(true)
|
|
expect(wrapper.findAll('.code-digit-value').map((item) => item.text())).toEqual(['', '', '', ''])
|
|
|
|
await wrapper.setProps({ codeSubmitting: true })
|
|
expect(wrapper.get('.code-entry-native-input').attributes('disabled')).toBeDefined()
|
|
expect(wrapper.get('.code-entry-action.primary').text()).toBe('正在查询')
|
|
|
|
wrapper.vm.showCodeEntryError('未找到该讲解编号,请确认后重试')
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.get('.code-entry-error').text()).toBe('未找到该讲解编号,请确认后重试')
|
|
|
|
await wrapper.get('.header-back').trigger('tap')
|
|
expect(wrapper.find('.code-entry-sheet').exists()).toBe(false)
|
|
expect(wrapper.get('.header-title').text()).toBe('免费讲解')
|
|
expect(wrapper.emitted('back')).toBeUndefined()
|
|
|
|
await wrapper.get('.header-back').trigger('tap')
|
|
expect(wrapper.emitted('back')).toEqual([[]])
|
|
})
|
|
|
|
it('展厅阶段使用完整展厅卡片资源', () => {
|
|
const wrapper = mount(ExplainHallSelect, {
|
|
props: {
|
|
stage: 'hall',
|
|
halls: [{
|
|
id: 'hall-dinosaur',
|
|
name: '恐龙厅',
|
|
floorLabel: 'L-2',
|
|
explainCount: 35,
|
|
guideStopCount: 35,
|
|
searchText: '恐龙厅'
|
|
}]
|
|
}
|
|
})
|
|
|
|
const card = wrapper.get('.hall-overview-card')
|
|
expect(wrapper.get('.header-title').text()).toBe('免费讲解')
|
|
expect(card.attributes('style')).toContain('--hall-card-color: #bb965a')
|
|
expect(card.get('.hall-full-card-image').attributes('src'))
|
|
.toBe('/static/icons/halls/portal-icons/dinosaur.png')
|
|
expect(card.find('.hall-overview-copy').exists()).toBe(false)
|
|
expect(card.find('.hall-go-entry').exists()).toBe(false)
|
|
})
|
|
|
|
it('讲解单元阶段显示单元目录并返回被选择的单元 ID', async () => {
|
|
const wrapper = mount(ExplainHallSelect, {
|
|
props: {
|
|
stage: 'unit',
|
|
selectedHallName: '生命演化厅',
|
|
businessUnits: [{
|
|
id: 'unit-origin',
|
|
name: '生命起源',
|
|
hallId: 'hall-evolution',
|
|
guideStopCount: 6
|
|
}]
|
|
}
|
|
})
|
|
|
|
const card = wrapper.get('.business-unit-card')
|
|
expect(wrapper.get('.header-title').text()).toBe('生命演化厅')
|
|
expect(card.text()).toContain('生命起源')
|
|
expect(card.text()).toContain('6 个讲解点')
|
|
|
|
await card.trigger('tap')
|
|
expect(wrapper.emitted('businessUnitClick')).toEqual([['unit-origin']])
|
|
})
|
|
|
|
it('READY 讲解点不显示可讲解标签,非 READY 讲解点保留图文标签和点击事件', async () => {
|
|
const readyStop = {
|
|
id: 'stop-ready',
|
|
name: '生命起源',
|
|
hallId: 'hall-evolution',
|
|
audioStatus: 'READY'
|
|
}
|
|
const textStop = {
|
|
id: 'stop-text',
|
|
name: '化石记录',
|
|
hallId: 'hall-evolution',
|
|
audioStatus: 'MISSING'
|
|
}
|
|
const wrapper = mount(ExplainHallSelect, {
|
|
props: {
|
|
stage: 'stop',
|
|
guideStops: [readyStop, textStop]
|
|
}
|
|
})
|
|
|
|
const cards = wrapper.findAll('.stop-card')
|
|
expect(cards).toHaveLength(2)
|
|
expect(wrapper.text()).toContain('生命起源')
|
|
expect(wrapper.text()).toContain('化石记录')
|
|
expect(wrapper.text()).not.toContain('可讲解')
|
|
expect(cards[0]?.find('.hall-meta-row').exists()).toBe(false)
|
|
expect(cards[1]?.find('.floor-badge').text()).toBe('图文')
|
|
|
|
await cards[0]?.trigger('tap')
|
|
await cards[1]?.trigger('tap')
|
|
expect(wrapper.emitted('guideStopClick')).toEqual([[readyStop], [textStop]])
|
|
})
|
|
})
|