85 lines
3.8 KiB
TypeScript
85 lines
3.8 KiB
TypeScript
import ElementPlus, { ElMessageBox } from 'element-plus'
|
|
import { createPinia, setActivePinia } from 'pinia'
|
|
import { flushPromises, mount } from '@vue/test-utils'
|
|
import { createMemoryHistory, createRouter } from 'vue-router'
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { useAuthStore } from '@/core/auth/auth'
|
|
import { useUnsavedWorkStore } from '@/core/unsaved-work/unsavedWork'
|
|
import { useWorkspaceTabsStore } from '@/core/workspace-tabs/workspaceTabs'
|
|
import WorkspaceTabs from './WorkspaceTabs.vue'
|
|
|
|
vi.mock('element-plus', async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import('element-plus')>()
|
|
return { ...actual, ElMessage: { error: vi.fn() }, ElMessageBox: { confirm: vi.fn() } }
|
|
})
|
|
|
|
async function mountTabs() {
|
|
const pinia = createPinia()
|
|
setActivePinia(pinia)
|
|
const auth = useAuthStore()
|
|
auth.token = 'token'
|
|
auth.user = { id: '1', name: '平台管理员', account: 'admin', roles: ['PLATFORM_ADMIN'] }
|
|
auth.permissions = ['platform:customer:list', 'platform:warehouse:list']
|
|
const router = createRouter({
|
|
history: createMemoryHistory(),
|
|
routes: [
|
|
{ path: '/customers', name: 'customers', component: { template: '<p />' }, meta: { requiresAuth: true, title: '客户管理' } },
|
|
{ path: '/warehouses', name: 'warehouses', component: { template: '<p />' }, meta: { requiresAuth: true, title: '仓库管理' } },
|
|
],
|
|
})
|
|
await router.push('/customers')
|
|
await router.isReady()
|
|
const workspace = useWorkspaceTabsStore()
|
|
workspace.initialize('1')
|
|
workspace.open({ id: 'warehouses', title: '仓库管理', path: '/warehouses' })
|
|
workspace.open({ id: 'customers', title: '客户管理', path: '/customers' })
|
|
const wrapper = mount(WorkspaceTabs, { attachTo: document.body, global: { plugins: [pinia, router, ElementPlus] } })
|
|
return { wrapper, router, workspace, unsaved: useUnsavedWorkStore() }
|
|
}
|
|
|
|
describe('WorkspaceTabs', () => {
|
|
beforeEach(() => {
|
|
sessionStorage.clear()
|
|
vi.mocked(ElMessageBox.confirm).mockReset()
|
|
})
|
|
afterEach(() => { document.body.innerHTML = '' })
|
|
|
|
it('keeps a dirty tab open when discard confirmation is cancelled', async () => {
|
|
const { wrapper, workspace, unsaved } = await mountTabs()
|
|
unsaved.upsert({ key: 'customer-form', label: '客户资料', dirty: true, requiredPermission: null, workspaceTabId: 'customers' })
|
|
vi.mocked(ElMessageBox.confirm).mockRejectedValueOnce('cancel')
|
|
|
|
await wrapper.get('[aria-label="关闭页签:客户管理"]').trigger('click')
|
|
await flushPromises()
|
|
|
|
expect(workspace.tabs.map((tab) => tab.id)).toContain('customers')
|
|
expect(wrapper.find('.workspace-tab.is-dirty').exists()).toBe(true)
|
|
})
|
|
|
|
it('closes confirmed dirty work and activates the most recent remaining tab', async () => {
|
|
const { wrapper, router, workspace, unsaved } = await mountTabs()
|
|
unsaved.upsert({ key: 'customer-form', label: '客户资料', dirty: true, requiredPermission: null, workspaceTabId: 'customers' })
|
|
vi.mocked(ElMessageBox.confirm).mockResolvedValueOnce({} as never)
|
|
|
|
await wrapper.get('[aria-label="关闭页签:客户管理"]').trigger('click')
|
|
await flushPromises()
|
|
|
|
expect(workspace.tabs.map((tab) => tab.id)).toEqual(['warehouses'])
|
|
expect(router.currentRoute.value.path).toBe('/warehouses')
|
|
expect(unsaved.findForWorkspace('customers')).toEqual([])
|
|
})
|
|
|
|
it('uses the mouse wheel to scroll an overflowing tab list horizontally', async () => {
|
|
const { wrapper } = await mountTabs()
|
|
const tabList = wrapper.get<HTMLElement>('.workspace-tab-list')
|
|
Object.defineProperties(tabList.element, {
|
|
clientWidth: { configurable: true, value: 320 },
|
|
scrollWidth: { configurable: true, value: 720 },
|
|
})
|
|
|
|
await tabList.trigger('wheel', { deltaY: 120 })
|
|
|
|
expect(tabList.element.scrollLeft).toBe(120)
|
|
})
|
|
})
|