import { flushPromises, mount } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import { createMemoryHistory, createRouter } from 'vue-router' import { describe, expect, it } from 'vitest' import { routes } from '@/router' import { useUiStore } from '@/stores/ui' import AppNav from './AppNav.vue' async function setup(initialPath = '/') { const pinia = createPinia() setActivePinia(pinia) const router = createRouter({ history: createMemoryHistory(), routes }) await router.push(initialPath) await router.isReady() const wrapper = mount(AppNav, { global: { plugins: [pinia, router] }, attachTo: document.body, }) return { wrapper, router, ui: useUiStore() } } describe('AppNav 导航', () => { it('渲染看板与今日两个入口', async () => { const { wrapper } = await setup() expect(wrapper.findAll('a').map((node) => node.text())).toEqual(['看板', '今日']) }) it('当前路由的入口标记 aria-current', async () => { const { wrapper } = await setup('/') const links = wrapper.findAll('a') expect(links[0]?.attributes('aria-current')).toBe('page') expect(links[1]?.attributes('aria-current')).toBeUndefined() }) it('在今日页时高亮今日入口', async () => { const { wrapper } = await setup('/today') const links = wrapper.findAll('a') expect(links[0]?.attributes('aria-current')).toBeUndefined() expect(links[1]?.attributes('aria-current')).toBe('page') }) it('点击可切换路由', async () => { const { wrapper, router } = await setup('/') await wrapper.findAll('a')[1]?.trigger('click') // 路由跳转是异步的,必须等 Promise 落地 await flushPromises() expect(router.currentRoute.value.path).toBe('/today') }) it('导航带可访问性标签', async () => { const { wrapper } = await setup() expect(wrapper.find('nav').attributes('aria-label')).toBe('主导航') }) }) describe('AppNav 应用级操作', () => { it('点击「备份」打开备份面板', async () => { const { wrapper, ui } = await setup() expect(ui.backupOpen).toBe(false) const backupButton = wrapper.findAll('button').find((node) => node.text() === '备份') await backupButton?.trigger('click') expect(ui.backupOpen).toBe(true) }) it('点击 ? 打开快捷键帮助', async () => { const { wrapper, ui } = await setup() await wrapper.find('button[aria-label="快捷键帮助"]').trigger('click') expect(ui.helpOpen).toBe(true) }) it('应用级操作在看板与今日视图下都可用', async () => { const { wrapper } = await setup('/today') expect(wrapper.findAll('button').map((node) => node.text())).toContain('备份') }) })