修复前端登录权限边界问题
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import { createMemoryHistory, createRouter } from 'vue-router'
|
||||
@@ -8,6 +9,7 @@ import ReservationOrderDetailView from '@/views/reservation/ReservationOrderDeta
|
||||
import ReservationOrderListView from '@/views/reservation/ReservationOrderListView.vue'
|
||||
import ReservationSourceMessageConversationView from '@/views/reservation/ReservationSourceMessageConversationView.vue'
|
||||
import ReservationTaskListView from '@/views/reservation/ReservationTaskListView.vue'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import type { SourceMessageConversationResult } from '@/types/reservation'
|
||||
|
||||
vi.mock('@/services/reservationService', async (importOriginal) => {
|
||||
@@ -91,18 +93,18 @@ function createTaskListResult(
|
||||
}
|
||||
}
|
||||
|
||||
function createOrderDetailResult() {
|
||||
function createOrderDetailResult(displayName = 'GRP-001') {
|
||||
return {
|
||||
order: {
|
||||
order_id: '20001',
|
||||
order_id: displayName === 'GRP-002' ? '20002' : '20001',
|
||||
hotel_id: 'HOTEL-TEST',
|
||||
order_status: 'ACTIVE',
|
||||
temporary_order_no: null,
|
||||
confirmation_number: null,
|
||||
group_code: 'GRP-001',
|
||||
group_code: displayName,
|
||||
block_code: null,
|
||||
allotment_code: null,
|
||||
display_name: 'GRP-001',
|
||||
display_name: displayName,
|
||||
created_at: '2026-07-08T03:00:00Z',
|
||||
updated_at: '2026-07-08T03:10:00Z',
|
||||
},
|
||||
@@ -238,7 +240,42 @@ function createDeferred<T>() {
|
||||
return { promise, resolve, reject }
|
||||
}
|
||||
|
||||
function createAuthPayload() {
|
||||
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,
|
||||
},
|
||||
{
|
||||
hotel_id: 'HOTEL-BKK',
|
||||
hotel_name: '曼谷酒店',
|
||||
time_zone: 'Asia/Bangkok',
|
||||
default_hotel: false,
|
||||
},
|
||||
],
|
||||
permissions: ['HOTEL_SWITCH'],
|
||||
menus: [],
|
||||
}
|
||||
}
|
||||
|
||||
async function mountWithPlugins(component: object, initialPath = '/', stubs: Record<string, unknown> = {}) {
|
||||
const pinia = createPinia()
|
||||
setActivePinia(pinia)
|
||||
const authStore = useAuthStore()
|
||||
authStore.applyLoginResult(createAuthPayload())
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh-CN',
|
||||
@@ -260,7 +297,7 @@ async function mountWithPlugins(component: object, initialPath = '/', stubs: Rec
|
||||
|
||||
return mount(component, {
|
||||
global: {
|
||||
plugins: [i18n, router],
|
||||
plugins: [pinia, i18n, router],
|
||||
stubs: {
|
||||
RouterLink: {
|
||||
template: '<a><slot /></a>',
|
||||
@@ -273,6 +310,8 @@ async function mountWithPlugins(component: object, initialPath = '/', stubs: Rec
|
||||
|
||||
describe('reservation P0 views', () => {
|
||||
beforeEach(() => {
|
||||
sessionStorage.clear()
|
||||
localStorage.clear()
|
||||
vi.mocked(service.fetchReservationOrderDetail).mockReset()
|
||||
vi.mocked(service.fetchReservationOrders).mockReset()
|
||||
vi.mocked(service.fetchReservationTaskList).mockReset()
|
||||
@@ -366,6 +405,27 @@ describe('reservation P0 views', () => {
|
||||
expect(wrapper.text()).toContain('第 3 / 4 页')
|
||||
})
|
||||
|
||||
it('reloads the order list when the selected hotel changes', async () => {
|
||||
vi.mocked(service.fetchReservationOrders)
|
||||
.mockResolvedValueOnce(createOrderListResult('GRP-001'))
|
||||
.mockResolvedValueOnce(createOrderListResult('GRP-002'))
|
||||
|
||||
const wrapper = await mountWithPlugins(ReservationOrderListView)
|
||||
await vi.dynamicImportSettled()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
authStore.setSelectedHotelId('HOTEL-BKK')
|
||||
await vi.dynamicImportSettled()
|
||||
|
||||
expect(service.fetchReservationOrders).toHaveBeenCalledTimes(2)
|
||||
expect(service.fetchReservationOrders).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
page_num: 1,
|
||||
}),
|
||||
)
|
||||
expect(wrapper.text()).toContain('GRP-002')
|
||||
})
|
||||
|
||||
it('renders task list items returned by the backend', async () => {
|
||||
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createTaskListResult('GRP-001', 'Booking Request'))
|
||||
|
||||
@@ -444,6 +504,48 @@ describe('reservation P0 views', () => {
|
||||
expect(wrapper.text()).toContain('第 2 / 3 页')
|
||||
})
|
||||
|
||||
it('reloads the task list when the selected hotel changes', async () => {
|
||||
vi.mocked(service.fetchReservationTaskList)
|
||||
.mockResolvedValueOnce(createTaskListResult('GRP-001', 'Booking Request'))
|
||||
.mockResolvedValueOnce(createTaskListResult('GRP-002', 'Booking Update'))
|
||||
|
||||
const wrapper = await mountWithPlugins(ReservationTaskListView)
|
||||
await vi.dynamicImportSettled()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
authStore.setSelectedHotelId('HOTEL-BKK')
|
||||
await vi.dynamicImportSettled()
|
||||
|
||||
expect(service.fetchReservationTaskList).toHaveBeenCalledTimes(2)
|
||||
expect(service.fetchReservationTaskList).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
page_num: 1,
|
||||
}),
|
||||
)
|
||||
expect(wrapper.text()).toContain('Booking Update')
|
||||
})
|
||||
|
||||
it('reloads order detail when the selected hotel changes', async () => {
|
||||
vi.mocked(service.fetchReservationOrderDetail)
|
||||
.mockResolvedValueOnce(createOrderDetailResult('GRP-001'))
|
||||
.mockResolvedValueOnce(createOrderDetailResult('GRP-002'))
|
||||
|
||||
const wrapper = await mountWithPlugins(ReservationOrderDetailView, '/reservation/orders/20001', {
|
||||
ReservationTaskDetailPanel: {
|
||||
template: '<section />',
|
||||
},
|
||||
})
|
||||
await vi.dynamicImportSettled()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
authStore.setSelectedHotelId('HOTEL-BKK')
|
||||
await vi.dynamicImportSettled()
|
||||
|
||||
expect(service.fetchReservationOrderDetail).toHaveBeenCalledTimes(2)
|
||||
expect(service.fetchReservationOrderDetail).toHaveBeenLastCalledWith('20001')
|
||||
expect(wrapper.text()).toContain('GRP-002')
|
||||
})
|
||||
|
||||
it('keeps the latest task list response when filters change quickly', async () => {
|
||||
const firstRequest = createDeferred<Awaited<ReturnType<typeof service.fetchReservationTaskList>>>()
|
||||
const secondRequest = createDeferred<Awaited<ReturnType<typeof service.fetchReservationTaskList>>>()
|
||||
|
||||
Reference in New Issue
Block a user