chore: initial commit

This commit is contained in:
2026-07-30 17:59:43 +08:00
commit dd0d365b03
73 changed files with 9898 additions and 0 deletions
+200
View File
@@ -0,0 +1,200 @@
import { beforeEach, describe, expect, expectTypeOf, it, vi } from 'vitest'
import { createPinia, setActivePinia } from 'pinia'
import { nextTick } from 'vue'
import { getNavigationLeaves } from '@/navigation/adminNavigation'
import { useAdminDataStore } from '@/stores/adminData'
import { PREVIEW_ROLE_KEY, useAccessPreviewStore } from '@/stores/accessPreview'
function createMemoryStorage(): Storage {
const values = new Map<string, string>()
return {
get length() {
return values.size
},
clear() {
values.clear()
},
getItem(key) {
return values.get(key) ?? null
},
key(index) {
return [...values.keys()][index] ?? null
},
removeItem(key) {
values.delete(key)
},
setItem(key, value) {
values.set(key, value)
},
}
}
describe('access preview store', () => {
beforeEach(() => {
setActivePinia(createPinia())
vi.stubGlobal('localStorage', createMemoryStorage())
})
it('defaults to the enabled super admin with all enabled permissions', () => {
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
expect(preview.enabledRoles).toHaveLength(5)
expect(preview.currentRole?.code).toBe('SUPER_ADMIN')
expect(preview.can('system:permission:write')).toBe(true)
expect(preview.firstAccessiblePath).toBe('/customers')
expect(localStorage.getItem(PREVIEW_ROLE_KEY)).toBe('R001')
})
it('ignores disabled permission resources even when the selected role still holds their ids', () => {
const data = useAdminDataStore()
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
const customerList = data.permissions.find((item) => item.code === 'platform:customer:list')
expect(customerList).toBeDefined()
if (customerList) customerList.status = '停用'
expect(preview.can('platform:customer:list')).toBe(false)
expect(getNavigationLeaves(preview.filteredNavigation).map((item) => item.path)).not.toContain('/customers')
expect(preview.firstAccessiblePath).toBe('/customers/reviews')
})
it('does not cascade a disabled directory to enabled descendant leaves', () => {
const data = useAdminDataStore()
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
const businessDirectory = data.permissions.find((item) => item.code === 'business')
expect(businessDirectory).toBeDefined()
if (businessDirectory) businessDirectory.status = '停用'
expect(preview.can('business')).toBe(false)
expect(preview.can('platform:customer:list')).toBe(true)
expect(getNavigationLeaves(preview.filteredNavigation).map((item) => item.path)).toContain('/customers')
})
it('reacts immediately to permission id changes and falls back when the current role is disabled', async () => {
const data = useAdminDataStore()
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
expect(preview.commitRole('R003')).toBe(true)
const operator = data.roles.find((item) => item.id === 'R003')
expect(operator).toBeDefined()
if (operator) operator.permissionIds = ['P100']
expect(preview.can('first-leg:list')).toBe(false)
expect(preview.can('platform:customer:list')).toBe(true)
expect(preview.permissionSignature).toBe('platform:customer:list')
if (operator) operator.status = '停用'
await nextTick()
expect(preview.currentRole?.code).toBe('SUPER_ADMIN')
expect(localStorage.getItem(PREVIEW_ROLE_KEY)).toBe('R001')
})
it('falls back from an invalid persisted role and reset clears selection and persistence', () => {
localStorage.setItem(PREVIEW_ROLE_KEY, 'missing-role')
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
expect(preview.currentRole?.code).toBe('SUPER_ADMIN')
preview.reset()
expect(preview.initialized).toBe(false)
expect(preview.currentRole).toBeNull()
expect(localStorage.getItem(PREVIEW_ROLE_KEY)).toBeNull()
})
it('restores an enabled persisted role', () => {
localStorage.setItem(PREVIEW_ROLE_KEY, 'R003')
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
expect(preview.currentRole?.id).toBe('R003')
expect(localStorage.getItem(PREVIEW_ROLE_KEY)).toBe('R003')
})
it('does not reload an initialized role during guarded navigation', () => {
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
expect(preview.commitRole('R003')).toBe(true)
localStorage.setItem(PREVIEW_ROLE_KEY, 'R001')
preview.initializeAfterLogin()
expect(preview.currentRole?.id).toBe('R003')
})
it('has no role, permissions, or route when every role is disabled', () => {
const data = useAdminDataStore()
data.roles.forEach((role) => {
role.status = '停用'
})
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
expect(preview.currentRole).toBeNull()
expect([...preview.permissionCodes]).toEqual([])
expect(preview.filteredNavigation).toEqual([])
expect(preview.firstAccessiblePath).toBeNull()
expect(localStorage.getItem(PREVIEW_ROLE_KEY)).toBeNull()
})
it('does not recreate a default preview after reset when role data changes', async () => {
const data = useAdminDataStore()
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
preview.reset()
data.roles[0].status = '停用'
data.roles[1].status = '停用'
await nextTick()
expect(preview.initialized).toBe(false)
expect(preview.selectedRoleId).toBeNull()
expect(preview.currentRole).toBeNull()
expect(localStorage.getItem(PREVIEW_ROLE_KEY)).toBeNull()
})
it('previews candidates without committing and rejects disabled roles', () => {
const data = useAdminDataStore()
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
const candidate = preview.previewRole('R003')
expect(candidate.codes.has('first-leg:create')).toBe(true)
expect(candidate.firstPath).toBe('/warehouses')
expect(getNavigationLeaves(candidate.navigation).map((item) => item.path)).toContain('/orders/first-leg')
expectTypeOf(candidate.codes).toEqualTypeOf<ReadonlySet<string>>()
expectTypeOf(preview.permissionCodes).toEqualTypeOf<ReadonlySet<string>>()
expect(preview.currentRole?.id).toBe('R001')
const finance = data.roles.find((item) => item.id === 'R004')
if (finance) finance.status = '停用'
expect(preview.commitRole('R004')).toBe(false)
expect(preview.previewRole('R004').firstPath).toBeNull()
expect(preview.currentRole?.id).toBe('R001')
})
it('does not filter or mutate mock business data when switching data scopes', () => {
const data = useAdminDataStore()
const preview = useAccessPreviewStore()
preview.initializeAfterLogin()
const customerSnapshot = JSON.parse(JSON.stringify(data.customers)) as typeof data.customers
const orderSnapshot = JSON.parse(JSON.stringify(data.orders)) as typeof data.orders
expect(preview.commitRole('R003')).toBe(true)
expect(preview.currentRole?.dataScope).toBe('本部门数据')
expect(preview.commitRole('R005')).toBe(true)
expect(preview.currentRole?.dataScope).toBe('本人数据')
expect(data.customers).toEqual(customerSnapshot)
expect(data.orders).toEqual(orderSnapshot)
})
})