import { flushPromises, mount } from '@vue/test-utils' import { defineComponent } from 'vue' import { createMemoryHistory, createRouter } from 'vue-router' import { describe, expect, it } from 'vitest' import { adminNavigation, filterAdminNavigation, type AdminNavigationNode } from '@/core/navigation/adminNavigation' import AdminSidebarMenu from './AdminSidebarMenu.vue' const visibleNavigation = filterAdminNavigation(adminNavigation, new Set([ 'platform:customer:list', 'platform:warehouse:list', 'platform:firstleg:inbound:list', 'platform:location:list', 'platform:pallet:list', 'firstleg:fba-pricing:rate:view', 'platform:express:list', 'platform:counterparty:list', 'platform:download:list', 'platform:user:list', 'platform:role:list', 'platform:permission:list', ])) const stubs = { 'el-menu': defineComponent({ props: ['defaultActive', 'defaultOpeneds', 'collapse'], emits: ['select'], methods: { updateActiveIndex() {} }, template: '', }), 'el-sub-menu': { props: ['index'], template: '
', }, 'el-menu-item': { props: ['index'], template: '', }, } describe('AdminSidebarMenu', () => { function routerPlugin() { return createRouter({ history: createMemoryHistory(), routes: [ { path: '/', component: { template: '

' } }, { path: '/warehouses', component: { template: '

' } }, ], }) } it('renders the visible phase-one modules and forwards the active route', () => { const wrapper = mount(AdminSidebarMenu, { props: { items: visibleNavigation, activePath: '/system/users', collapsed: false }, global: { stubs, plugins: [routerPlugin()] }, }) expect(wrapper.get('nav').attributes('data-active')).toBe('/system/users') expect(wrapper.get('nav').attributes('data-openeds')).toBe('[]') const groupTitles = wrapper.findAll('[data-kind="group"] header').map((node) => node.text()) const paths = wrapper.findAll('[data-kind="item"]').map((node) => node.attributes('data-index')) expect(groupTitles).toContain('客户管理') expect(groupTitles).not.toContain('供应商中心') expect(groupTitles).toContain('通用') expect(groupTitles).toContain('系统管理') expect(groupTitles).not.toContain('预约管理') expect(groupTitles).not.toContain('财务管理') expect(paths).not.toContain('/finance/customer-accounts') expect(paths).toContain('/dashboard') expect(paths).toContain('/orders') expect(paths).not.toContain('/master-data/express-companies') expect(paths).not.toContain('/orders/first-leg') expect(paths).not.toContain('/first-leg-pricing/customer-rules') expect(paths).toContain('/downloads') expect(paths).not.toContain('/prototype/reports/overview') expect(paths).toContain('/system/permissions') }) it('forwards desktop collapse state to Element Plus', () => { const wrapper = mount(AdminSidebarMenu, { props: { items: visibleNavigation, activePath: '/', collapsed: true }, global: { stubs, plugins: [routerPlugin()] }, }) expect(wrapper.get('nav').attributes('data-collapsed')).toBe('true') }) it('renders only entries included in the filtered navigation input', () => { const items = filterAdminNavigation(adminNavigation, new Set(['platform:permission:list'])) const wrapper = mount(AdminSidebarMenu, { props: { items, activePath: '/', collapsed: false }, global: { stubs, plugins: [routerPlugin()] }, }) expect(wrapper.text()).toContain('菜单权限') expect(wrapper.text()).toContain('首页数据看板') expect(wrapper.text()).not.toContain('客户列表') }) it('recursively renders three navigation levels', () => { const items: AdminNavigationNode[] = [{ key: 'operations', title: '运营管理', icon: adminNavigation[0].icon, children: [{ key: 'shipment', title: '运输管理', icon: adminNavigation[0].icon, children: [{ key: 'tracking', title: '轨迹管理', icon: adminNavigation[0].icon, path: '/tracking', permission: 'tracking:list', }], }], }] const wrapper = mount(AdminSidebarMenu, { props: { items, activePath: '/tracking', collapsed: false }, global: { stubs, plugins: [routerPlugin()] }, }) expect(wrapper.findAll('[data-kind="group"]')).toHaveLength(2) expect(wrapper.get('[data-kind="item"]').attributes('data-index')).toBe('/tracking') }) it('recreates the menu when asynchronously loaded groups change', async () => { const wrapper = mount(AdminSidebarMenu, { props: { items: [adminNavigation[0]], activePath: '/dashboard', collapsed: false }, global: { stubs, plugins: [routerPlugin()] }, }) const initialMenu = wrapper.get('nav').element await wrapper.setProps({ items: visibleNavigation }) expect(wrapper.get('nav').element).not.toBe(initialMenu) expect(wrapper.text()).toContain('系统管理') }) it('navigates explicitly when a leaf menu item is selected', async () => { const router = routerPlugin() await router.push('/') const wrapper = mount(AdminSidebarMenu, { props: { items: visibleNavigation, activePath: '/', collapsed: false }, global: { stubs, plugins: [router] }, }) await wrapper.get('nav').trigger('click') await flushPromises() expect(router.currentRoute.value.path).toBe('/warehouses') }) })