72 lines
4.6 KiB
TypeScript
72 lines
4.6 KiB
TypeScript
import ElementPlus, { type FormInstance } from 'element-plus'
|
|
import { createPinia, setActivePinia } from 'pinia'
|
|
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
|
|
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
import { useAuthStore } from '@/core/auth/auth'
|
|
import AppDialog from '@/shared/components/AppDialog.vue'
|
|
import { createPlatformPermission, listPlatformPermissions, updatePlatformPermission } from '../api/platformIam'
|
|
import PermissionsView from './PermissionsView.vue'
|
|
|
|
vi.mock('../api/platformIam', () => ({
|
|
listPlatformPermissions: vi.fn(), createPlatformPermission: vi.fn(), updatePlatformPermission: vi.fn(),
|
|
changePlatformPermissionStatus: vi.fn(), deletePlatformPermission: vi.fn(),
|
|
}))
|
|
|
|
enableAutoUnmount(afterEach)
|
|
afterEach(() => { document.body.innerHTML = ''; vi.unstubAllGlobals(); vi.clearAllMocks() })
|
|
|
|
describe('permission editor modal', () => {
|
|
it.each(['create', 'edit'])('keeps the %s form in the centered dialog and preserves failed writes', async mode => {
|
|
vi.stubGlobal('ResizeObserver', class { observe() {} unobserve() {} disconnect() {} })
|
|
const pinia = createPinia()
|
|
setActivePinia(pinia)
|
|
const auth = useAuthStore()
|
|
auth.isServerSession = true
|
|
auth.permissions = ['platform:permission:list', 'platform:permission:create', 'platform:permission:edit']
|
|
vi.mocked(listPlatformPermissions).mockResolvedValue([{
|
|
id: '90071992547409931', tenantId: 0, appCode: 'PLATFORM', permissionType: 'MENU', parentId: 0,
|
|
permissionCode: 'platform:sample:list', permissionName: '测试菜单', routePath: '/sample',
|
|
httpMethod: null, sortNo: 10, status: 'ACTIVE',
|
|
}])
|
|
vi.mocked(createPlatformPermission).mockRejectedValue(new Error('保存失败'))
|
|
vi.mocked(updatePlatformPermission).mockRejectedValue(new Error('保存失败'))
|
|
const wrapper = mount(PermissionsView, { attachTo: document.body, global: { plugins: [pinia, ElementPlus] } })
|
|
await flushPromises()
|
|
await wrapper.findAll(mode === 'create' ? 'button' : '.el-table__body-wrapper button').find(button => button.text().trim() === (mode === 'create' ? '新增权限' : '编辑'))!.trigger('click')
|
|
await flushPromises()
|
|
|
|
const dialog = document.querySelector<HTMLElement>('.el-dialog.permission-editor-dialog.admin-density-dialog')!
|
|
expect(dialog).not.toBeNull()
|
|
expect(dialog.style.getPropertyValue('--el-dialog-width')).toBe('min(720px, calc(100vw - 28px))')
|
|
expect(document.querySelector('.el-drawer')).toBeNull()
|
|
expect(dialog.querySelectorAll('.el-form-item')).toHaveLength(6)
|
|
const codeInput = dialog.querySelector<HTMLInputElement>('input[placeholder="如:platform:customer:list"]')
|
|
if (mode === 'edit') { expect(codeInput).toBeNull(); expect(dialog.textContent).toContain('platform:sample:list') }
|
|
else expect(codeInput?.disabled).toBe(false)
|
|
// Vitest externalizes Element Plus: its CJS validator interop differs from the Vite browser bundle.
|
|
// Exercise the dialog's validation gate explicitly, without changing production rules.
|
|
const form = wrapper.findComponent({ name: 'ElForm' })
|
|
expect(form.props('rules').name).toEqual(expect.arrayContaining([expect.objectContaining({ required: true })]))
|
|
const validate = vi.spyOn(form.vm.$.exposed as FormInstance, 'validate').mockResolvedValue(true)
|
|
if (mode === 'create') {
|
|
validate.mockRejectedValueOnce({ name: [{ message: '请输入权限名称' }] })
|
|
wrapper.getComponent(AppDialog).vm.$emit('confirm')
|
|
await flushPromises()
|
|
expect(createPlatformPermission).not.toHaveBeenCalled()
|
|
for (const [placeholder, value] of [['用户可理解的中文名称', '新增菜单'], ['如:platform:customer:list', 'platform:new:list'], ['如:/customers', '/new']]) {
|
|
const input = dialog.querySelector<HTMLInputElement>(`input[placeholder="${placeholder}"]`)!
|
|
input.value = value!
|
|
input.dispatchEvent(new Event('input', { bubbles: true }))
|
|
}
|
|
}
|
|
await flushPromises()
|
|
wrapper.getComponent(AppDialog).vm.$emit('confirm')
|
|
await flushPromises()
|
|
if (mode === 'create') expect(createPlatformPermission).toHaveBeenCalledWith({ type: 'MENU', code: 'platform:new:list', name: '新增菜单', parentId: '0', routePath: '/new', httpMethod: null, sortNo: 10 })
|
|
else expect(updatePlatformPermission).toHaveBeenCalledWith('90071992547409931', { name: '测试菜单', parentId: null, routePath: '/sample', httpMethod: null, sortNo: 10 })
|
|
expect(wrapper.getComponent(AppDialog).props('modelValue')).toBe(true)
|
|
if (mode === 'create') expect(codeInput?.value).toBe('platform:new:list')
|
|
else expect(dialog.textContent).toContain('platform:sample:list')
|
|
})
|
|
})
|