135 lines
3.6 KiB
TypeScript
135 lines
3.6 KiB
TypeScript
// @vitest-environment happy-dom
|
|
|
|
import { defineComponent } from 'vue'
|
|
import { mount } from '@vue/test-utils'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import GuideMapShell from '@/components/navigation/GuideMapShell.vue'
|
|
|
|
const ThreeMapStub = defineComponent({
|
|
name: 'ThreeMap',
|
|
props: {
|
|
initialFloorId: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
initialView: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
visiblePoiIds: {
|
|
type: Array,
|
|
default: null
|
|
},
|
|
targetFocus: {
|
|
type: Object,
|
|
default: null
|
|
}
|
|
},
|
|
emits: ['floor-change', 'target-focus'],
|
|
setup(_, { expose }) {
|
|
expose({ switchFloor: vi.fn() })
|
|
return {}
|
|
},
|
|
template: '<div data-testid="three-map"></div>'
|
|
})
|
|
|
|
const modelSource = {
|
|
loadPackage: async () => ({ overviewModelUrl: '', floors: [] }),
|
|
loadFloorPois: async () => []
|
|
}
|
|
|
|
const mountShell = (visiblePoiIds: string[] | null) => mount(GuideMapShell, {
|
|
props: {
|
|
mapType: 'indoor',
|
|
indoorModelSource: modelSource,
|
|
floors: [
|
|
{ id: 'L1', label: '1F' },
|
|
{ id: 'L2', label: '2F' }
|
|
],
|
|
activeFloor: 'L1',
|
|
visiblePoiIds
|
|
},
|
|
global: {
|
|
stubs: {
|
|
ThreeMap: ThreeMapStub
|
|
}
|
|
}
|
|
})
|
|
|
|
describe('GuideMapShell 点位过滤契约', () => {
|
|
it.each([
|
|
['不过滤时透传 null', null],
|
|
['无结果时透传空列表', []],
|
|
['有结果时透传精确 ID', ['poi-a', 'poi-b']]
|
|
])('%s', (_label, visiblePoiIds) => {
|
|
const wrapper = mountShell(visiblePoiIds as string[] | null)
|
|
expect(wrapper.getComponent(ThreeMapStub).props('visiblePoiIds')).toEqual(visiblePoiIds)
|
|
})
|
|
|
|
it('原样转发跨楼层与目标聚焦结果', async () => {
|
|
const wrapper = mountShell(['poi-l2'])
|
|
const renderer = wrapper.getComponent(ThreeMapStub)
|
|
const focusResult = {
|
|
requestId: 3,
|
|
poiId: 'poi-l2',
|
|
floorId: 'L2',
|
|
status: 'focused' as const
|
|
}
|
|
|
|
renderer.vm.$emit('floor-change', 'L2')
|
|
renderer.vm.$emit('target-focus', focusResult)
|
|
await wrapper.vm.$nextTick()
|
|
|
|
expect(wrapper.emitted('floorChange')).toEqual([['L2']])
|
|
expect(wrapper.emitted('targetFocus')).toEqual([[focusResult]])
|
|
})
|
|
|
|
it('动态楼层业务视图不会覆盖首次外观模型初始化视图', () => {
|
|
const wrapper = mount(GuideMapShell, {
|
|
props: {
|
|
mapType: 'indoor',
|
|
indoorModelSource: modelSource,
|
|
floors: [
|
|
{ id: 'L1', label: '1F' },
|
|
{ id: 'L2', label: '2F' }
|
|
],
|
|
activeFloor: 'L2',
|
|
indoorView: 'floor',
|
|
indoorInitialView: 'overview'
|
|
},
|
|
global: {
|
|
stubs: {
|
|
ThreeMap: ThreeMapStub
|
|
}
|
|
}
|
|
})
|
|
|
|
const renderer = wrapper.getComponent(ThreeMapStub)
|
|
expect(renderer.props('initialFloorId')).toBe('L2')
|
|
expect(renderer.props('initialView')).toBe('overview')
|
|
})
|
|
|
|
it('外观状态点击当前业务楼层仍请求渲染器,且等待 floor-change 才提交业务视图', async () => {
|
|
const wrapper = mount(GuideMapShell, {
|
|
props: {
|
|
mapType: 'indoor',
|
|
indoorModelSource: modelSource,
|
|
floors: [{ id: 'L2', label: '2F' }],
|
|
activeFloor: 'L2',
|
|
indoorView: 'overview',
|
|
indoorInitialView: 'overview'
|
|
},
|
|
global: { stubs: { ThreeMap: ThreeMapStub } }
|
|
})
|
|
const renderer = wrapper.getComponent(ThreeMapStub)
|
|
|
|
await (wrapper.vm as any).switchFloor('L2')
|
|
expect((renderer.vm as any).switchFloor).toHaveBeenCalledWith('L2')
|
|
expect(wrapper.emitted('indoorViewChange')).toBeUndefined()
|
|
|
|
renderer.vm.$emit('floor-change', 'L2')
|
|
await wrapper.vm.$nextTick()
|
|
expect(wrapper.emitted('indoorViewChange')).toEqual([['floor']])
|
|
})
|
|
})
|