119 lines
4.6 KiB
TypeScript
119 lines
4.6 KiB
TypeScript
import { createPinia, setActivePinia } from 'pinia'
|
|
import { flushPromises, shallowMount } from '@vue/test-utils'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { createPlatformRole, listPlatformInternalUsers, listPlatformPermissions, listPlatformRoles, type PlatformRoleResource } from '@/modules/iam/api/platformIam'
|
|
import { useAuthStore } from '@/core/auth/auth'
|
|
import RolesView from './RolesView.vue'
|
|
|
|
vi.mock('@/modules/iam/api/platformIam', () => ({
|
|
createPlatformRole: vi.fn(),
|
|
listPlatformInternalUsers: vi.fn(),
|
|
listPlatformPermissions: vi.fn(),
|
|
listPlatformRoles: vi.fn(),
|
|
updatePlatformRole: vi.fn(),
|
|
changePlatformRoleStatus: vi.fn(),
|
|
deletePlatformRole: vi.fn(),
|
|
replacePlatformRolePermissions: vi.fn(),
|
|
}))
|
|
|
|
const platformRole: PlatformRoleResource = {
|
|
id: 4000002,
|
|
tenantId: 0,
|
|
appCode: 'PLATFORM',
|
|
roleCode: 'CUSTOMER_REVIEWER',
|
|
roleName: '企业审核员',
|
|
roleType: 'SYSTEM',
|
|
status: 'ACTIVE',
|
|
description: '企业资料与入驻审核',
|
|
}
|
|
|
|
function mountView(pinia = createPinia()) {
|
|
setActivePinia(pinia)
|
|
const auth = useAuthStore()
|
|
if (auth.permissions.length === 0) auth.permissions = ['platform:role:list', 'platform:role:create', 'platform:role:grant']
|
|
return shallowMount(RolesView, {
|
|
global: {
|
|
plugins: [pinia],
|
|
directives: { loading: () => undefined },
|
|
stubs: {
|
|
AdminPage: { template: '<main><slot /></main>' },
|
|
ListPageLayout: { template: '<section><slot name="toolbar" /><slot name="state" /><slot /></section>' },
|
|
FormSection: { template: '<section><slot /></section>' },
|
|
AppDrawer: { template: '<section><slot /><slot name="footer" /></section>' },
|
|
LoadErrorState: { props: ['message'], template: '<div role="alert">{{ message }}<slot name="details" /></div>' },
|
|
DataTable: { props: ['data'], template: '<section><slot name="toolbar-actions" /><span data-testid="row-count">{{ data.length }}</span></section>' },
|
|
'el-alert': { props: ['title'], template: '<div role="alert">{{ title }}<slot name="title" /></div>' },
|
|
'el-input': true,
|
|
'el-option': true,
|
|
'el-select': true,
|
|
'el-button': true,
|
|
'el-table': true,
|
|
'el-table-column': true,
|
|
'el-tag': true,
|
|
'el-radio-group': true,
|
|
'el-radio-button': true,
|
|
'el-drawer': {
|
|
props: ['modelValue'],
|
|
template: '<section><slot /><slot name="footer" /></section>',
|
|
},
|
|
'el-form': { template: '<form><slot /></form>' },
|
|
'el-form-item': { template: '<label><slot /></label>' },
|
|
'el-tree': {
|
|
props: { checkStrictly: Boolean },
|
|
template: '<div data-testid="permission-tree" :data-check-strictly="String(checkStrictly)" />',
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
describe('RolesView', () => {
|
|
beforeEach(() => {
|
|
setActivePinia(createPinia())
|
|
vi.mocked(listPlatformRoles).mockReset()
|
|
vi.mocked(listPlatformPermissions).mockReset()
|
|
vi.mocked(listPlatformInternalUsers).mockReset()
|
|
vi.mocked(listPlatformPermissions).mockResolvedValue([])
|
|
vi.mocked(listPlatformInternalUsers).mockResolvedValue([])
|
|
vi.mocked(createPlatformRole).mockReset()
|
|
})
|
|
|
|
it('keeps directory, menu, and action permissions independently checkable', () => {
|
|
const wrapper = mountView()
|
|
|
|
expect(wrapper.get('[data-testid="permission-tree"]').attributes('data-check-strictly')).toBe('true')
|
|
})
|
|
|
|
it('loads platform roles from IAM for a server session', async () => {
|
|
const pinia = createPinia()
|
|
setActivePinia(pinia)
|
|
const auth = useAuthStore()
|
|
auth.isServerSession = true
|
|
auth.permissions = ['platform:role:list', 'platform:role:create']
|
|
vi.mocked(listPlatformRoles).mockResolvedValue([platformRole])
|
|
|
|
const wrapper = mountView(pinia)
|
|
await flushPromises()
|
|
|
|
expect(listPlatformRoles).toHaveBeenCalledTimes(1)
|
|
expect(listPlatformInternalUsers).toHaveBeenCalledTimes(1)
|
|
expect(wrapper.get('[data-testid="row-count"]').text()).toBe('1')
|
|
expect(wrapper.text()).not.toContain('角色负责聚合菜单、操作和数据范围,内部用户可分配多个角色')
|
|
expect(wrapper.find('[data-testid="permission-tree"]').exists()).toBe(false)
|
|
})
|
|
|
|
it('keeps a failed IAM role list recoverable', async () => {
|
|
const pinia = createPinia()
|
|
setActivePinia(pinia)
|
|
const auth = useAuthStore()
|
|
auth.isServerSession = true
|
|
auth.permissions = ['platform:role:list']
|
|
vi.mocked(listPlatformRoles).mockRejectedValue(new Error('IAM unavailable'))
|
|
|
|
const wrapper = mountView(pinia)
|
|
await flushPromises()
|
|
|
|
expect(wrapper.findAll('[role="alert"]').map((item) => item.text()).join(' ')).toContain('IAM unavailable')
|
|
})
|
|
})
|