接入前端登录权限底座

This commit is contained in:
andy committed 2026-07-09 20:42:16 +08:00
1 parent c190d5e3a8
commit e49b2ccc1d
27 files changed
+1745 -68

No files matched your search

+91 -8
View File
@@ -1,13 +1,15 @@
import { mount } from '@vue/test-utils'
import { createPinia } from 'pinia'
import { createPinia, setActivePinia } from 'pinia'
import { createI18n } from 'vue-i18n'
import { createMemoryHistory, createRouter } from 'vue-router'
import { describe, expect, it, vi } from 'vitest'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import ReservationAppShell from '@/layouts/ReservationAppShell.vue'
import enUS from '@/i18n/locales/en-US'
import thTH from '@/i18n/locales/th-TH'
import zhCN from '@/i18n/locales/zh-CN'
import { useAuthStore } from '@/stores/authStore'
import type { AuthMenuResult } from '@/types/auth'
vi.mock('@/services/healthService', () => ({
fetchBackendHealth: vi.fn().mockResolvedValue({
@@ -16,7 +18,68 @@ vi.mock('@/services/healthService', () => ({
}),
}))
async function mountShell() {
function createAuthPayload(menus: AuthMenuResult[]) {
return {
access_token: 'session-token',
token_type: 'Bearer',
expires_at: '2026-07-09T12:00:00Z',
user: {
id: '1900000000000000001',
username: 'admin',
display_name: '系统管理员',
super_admin: true,
},
default_hotel_id: 'HOTEL-TEST',
hotels: [
{
hotel_id: 'HOTEL-TEST',
hotel_name: '测试酒店',
time_zone: 'Asia/Bangkok',
default_hotel: true,
},
],
permissions: ['RESERVATION_ORDER_READ', 'RESERVATION_TASK_READ'],
menus,
}
}
function createReservationOrdersMenu(): AuthMenuResult {
return {
menu_code: 'RESERVATION_ORDERS',
menu_name: '订单列表',
route_path: '/reservation/orders',
component_key: 'ReservationOrders',
icon_key: 'pi pi-list',
permission_code: 'RESERVATION_ORDER_READ',
sort_order: 10,
}
}
function createReservationTasksMenu(): AuthMenuResult {
return {
menu_code: 'RESERVATION_TASKS',
menu_name: '任务队列',
route_path: '/reservation/tasks',
component_key: 'ReservationTasks',
icon_key: 'pi pi-check-square',
permission_code: 'RESERVATION_TASK_READ',
sort_order: 20,
}
}
function createDebugMenu(): AuthMenuResult {
return {
menu_code: 'DEBUG_EML_SUPERAGENT',
menu_name: 'Debug EML',
route_path: '/debug/eml-superagent',
component_key: 'DebugEmlSuperAgent',
icon_key: 'pi pi-upload',
permission_code: 'SYSTEM_DEBUG_EML_RUN',
sort_order: 30,
}
}
async function mountShell(menus = [createReservationOrdersMenu(), createReservationTasksMenu()]) {
const i18n = createI18n({
legacy: false,
locale: 'zh-CN',
@@ -47,12 +110,15 @@ async function mountShell() {
},
],
})
const pinia = createPinia()
setActivePinia(pinia)
useAuthStore().applyLoginResult(createAuthPayload(menus))
await router.push('/reservation/orders')
await router.isReady()
return mount(ReservationAppShell, {
global: {
plugins: [i18n, router, createPinia()],
plugins: [i18n, router, pinia],
},
slots: {
default: '<section />',
@@ -61,6 +127,10 @@ async function mountShell() {
}
describe('ReservationAppShell', () => {
beforeEach(() => {
sessionStorage.clear()
})
it('switches between Chinese, English, and Thai labels', async () => {
const wrapper = await mountShell()
@@ -73,12 +143,25 @@ describe('ReservationAppShell', () => {
expect(wrapper.text()).toContain('Order list')
})
it('shows the Debug EML navigation entry before menu management takes over permissions', async () => {
it('renders navigation from backend menus and hides Debug EML when the menu is absent', async () => {
const wrapper = await mountShell()
const debugLink = wrapper.find('a[href="/debug/eml-superagent"]')
expect(wrapper.find('a[href="/reservation/orders"]').exists()).toBe(true)
expect(wrapper.find('a[href="/reservation/tasks"]').exists()).toBe(true)
expect(wrapper.find('a[href="/debug/eml-superagent"]').exists()).toBe(false)
})
expect(debugLink.exists()).toBe(true)
expect(debugLink.text()).toContain('Debug EML')
it('shows Debug EML only when backend menus include it', async () => {
const wrapper = await mountShell([createReservationOrdersMenu(), createDebugMenu()])
expect(wrapper.find('a[href="/debug/eml-superagent"]').exists()).toBe(true)
expect(wrapper.text()).toContain('Debug EML')
})
it('shows current user and hotel context in the top bar', async () => {
const wrapper = await mountShell()
expect(wrapper.text()).toContain('系统管理员')
expect(wrapper.text()).toContain('测试酒店')
})
})