Files
workspace/code/fms/fms-vue/tests/views/layout-tabs-tools.spec.js
T
2026-09-21 23:13:14 +08:00

129 lines
5.2 KiB
JavaScript

/**
* 页签栏右侧工具区(照 vben 的 TabsTool*):更多 / 刷新当前页 / 内容最大化。
* 挂载真实 App(布局、页签、store、路由全真),覆盖:
* 1. 三个工具按钮渲染
* 2. 内容最大化:顶栏摘除 + is-maximized 标记(侧栏由该标记隐藏),页签栏保留;再次点击还原
* 3. 刷新按钮:当前页刷新计数 +1(页面组件重挂载由 keepalive-cache 用例覆盖)
* 4. 「更多」菜单 = 当前激活页签的上下文菜单(与右键菜单同源),点击菜单项生效
*/
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { flushPromises, mount } from '@vue/test-utils'
vi.mock('@/views/dashboard/index.vue', () => ({
default: { name: 'Dashboard', template: '<div data-page="Dashboard">DB</div>' },
}))
vi.mock('@/views/module/module-management/index.vue', () => ({
default: { name: 'ModuleManagement', template: '<div data-page="ModuleManagement">MM</div>' },
}))
vi.mock('@/views/module/menu-management/index.vue', () => ({
default: { name: 'MenuManagement', template: '<div data-page="MenuManagement">MENU</div>' },
}))
vi.mock('@/views/detail/DetailPage.vue', () => ({
default: { name: 'DetailPageStub', props: ['id'], template: '<div data-page="Detail" />' },
}))
vi.mock('@/services/api', () => ({
loadDataApi: vi.fn(() => Promise.resolve({ data: [], code: 0, success: true })),
describeApi: vi.fn(() => Promise.resolve({ data: [], code: 0, success: true })),
saveObjectApi: vi.fn(() => Promise.resolve({ code: 0, success: true })),
nextIdApi: vi.fn(() => Promise.resolve({ data: 1, code: 0, success: true })),
}))
import App from '@/App.vue'
import router from '@/router'
import { createTestPinia } from '../helpers/app.js'
import { useAuthStore } from '@/stores/auth'
import { useAppStore } from '@/stores/app'
beforeEach(async () => {
localStorage.clear()
sessionStorage.clear()
createTestPinia()
// 模块中心 /module/* 在路由层仅 g3soft 放行
useAuthStore().setSession({ token: 't', user: { id: 1, account: 'g3soft', name: 'U' } }, 'ORG')
await router.push('/dashboard')
await router.isReady()
})
async function mountApp() {
const wrapper = mount(App, { global: { plugins: [router] }, attachTo: document.body })
await flushPromises()
return wrapper
}
const TOOL_MORE = 0
const TOOL_REFRESH = 1
const TOOL_MAXIMIZE = 2
describe('页签栏右侧工具区', () => {
it('渲染三个工具按钮:更多 / 刷新 / 内容最大化', async () => {
const wrapper = await mountApp()
expect(wrapper.findAll('.fms-tabs-tool')).toHaveLength(3)
wrapper.unmount()
})
it('内容最大化:顶栏摘除、侧栏标记隐藏,页签栏保留;再次点击还原', async () => {
const wrapper = await mountApp()
const app = useAppStore()
// 最大化前:顶栏在、无 is-maximized 标记
expect(wrapper.find('.fms-topbar').exists()).toBe(true)
expect(wrapper.find('.fms-layout').classes()).not.toContain('is-maximized')
await wrapper.findAll('.fms-tabs-tool')[TOOL_MAXIMIZE].trigger('click')
expect(app.contentMaximized).toBe(true)
// 顶栏由模板 v-if 摘除;侧栏由 .is-maximized 的 display:none 隐藏(jsdom 不算样式,断言标记)
expect(wrapper.find('.fms-topbar').exists()).toBe(false)
expect(wrapper.find('.fms-layout').classes()).toContain('is-maximized')
// 页签栏保留 —— 它是还原入口
expect(wrapper.find('.fms-tabs').exists()).toBe(true)
await wrapper.findAll('.fms-tabs-tool')[TOOL_MAXIMIZE].trigger('click')
expect(app.contentMaximized).toBe(false)
expect(wrapper.find('.fms-topbar').exists()).toBe(true)
wrapper.unmount()
})
it('刷新按钮:点击后当前页刷新计数 +1', async () => {
const wrapper = await mountApp()
await router.push('/module/module-management')
await flushPromises()
const app = useAppStore()
const before = app.getRouteRefreshKey('/module/module-management')
await wrapper.findAll('.fms-tabs-tool')[TOOL_REFRESH].trigger('click')
expect(app.getRouteRefreshKey('/module/module-management')).toBe(before + 1)
wrapper.unmount()
})
it('更多菜单:为当前激活页签的上下文菜单,点击「关闭其他」生效', async () => {
const wrapper = await mountApp()
// 制造多个页签:工作台 + 菜单管理 + 模块管理(激活)
await router.push('/module/menu-management')
await flushPromises()
await router.push('/module/module-management')
await flushPromises()
await wrapper.findAll('.fms-tabs-tool')[TOOL_MORE].trigger('click')
await flushPromises()
// 浮层经 Teleport 渲染到 body
const menuItems = Array.from(document.querySelectorAll('.dropdown-item'))
const labels = menuItems.map((el) => el.textContent.trim())
expect(labels).toContain('刷新')
expect(labels).toContain('关闭其他')
expect(labels).toContain('关闭全部')
const closeOthers = menuItems.find((el) => el.textContent.trim() === '关闭其他')
closeOthers.click()
await flushPromises()
// 仅保留工作台与当前激活页签
const app = useAppStore()
expect(app.visitedTabs.map((t) => t.key)).toEqual(['/dashboard', '/module/module-management'])
wrapper.unmount()
})
})