接入前端P0页面真实接口
This commit is contained in:
165
client/src/tests/reservationViews.spec.ts
Normal file
165
client/src/tests/reservationViews.spec.ts
Normal file
@@ -0,0 +1,165 @@
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import { createMemoryHistory, createRouter } from 'vue-router'
|
||||
|
||||
import zhCN from '@/i18n/locales/zh-CN'
|
||||
import { EndpointPendingError } from '@/services/reservationService'
|
||||
import ReservationOrderListView from '@/views/reservation/ReservationOrderListView.vue'
|
||||
import ReservationSourceMessageConversationView from '@/views/reservation/ReservationSourceMessageConversationView.vue'
|
||||
import ReservationTaskListView from '@/views/reservation/ReservationTaskListView.vue'
|
||||
|
||||
vi.mock('@/services/reservationService', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@/services/reservationService')>()
|
||||
return {
|
||||
...actual,
|
||||
fetchReservationOrders: vi.fn(),
|
||||
fetchReservationTaskList: vi.fn(),
|
||||
fetchSourceMessageConversation: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
const service = await import('@/services/reservationService')
|
||||
|
||||
function createTaskListResult(displayOrderKey: string, sourceSubject: string) {
|
||||
return {
|
||||
items: [
|
||||
{
|
||||
task_id: displayOrderKey === 'GRP-NEW' ? '10002' : '10001',
|
||||
order_id: '20001',
|
||||
hotel_id: 'HOTEL-TEST',
|
||||
display_order_key: displayOrderKey,
|
||||
temporary_order_no: null,
|
||||
task_type: 'NEW_BOOKING',
|
||||
task_subtype: 'NEW_BOOKING',
|
||||
task_status: 'PENDING_CONFIRM',
|
||||
card_name: 'New Booking',
|
||||
queue_sequence: 1,
|
||||
queue_participation: true,
|
||||
can_process: true,
|
||||
readonly_reason_code: null,
|
||||
source_message_id: '30001',
|
||||
source_subject: sourceSubject,
|
||||
source_sender_summary: null,
|
||||
source_received_at: null,
|
||||
external_conversation_id: null,
|
||||
conversation_message_count: null,
|
||||
created_at: '2026-07-08T03:00:00Z',
|
||||
updated_at: '2026-07-08T03:10:00Z',
|
||||
},
|
||||
],
|
||||
page: {
|
||||
page_num: 1,
|
||||
page_size: 20,
|
||||
total: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function createDeferred<T>() {
|
||||
let resolve!: (value: T) => void
|
||||
let reject!: (reason?: unknown) => void
|
||||
const promise = new Promise<T>((promiseResolve, promiseReject) => {
|
||||
resolve = promiseResolve
|
||||
reject = promiseReject
|
||||
})
|
||||
return { promise, resolve, reject }
|
||||
}
|
||||
|
||||
async function mountWithPlugins(component: object, initialPath = '/') {
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh-CN',
|
||||
messages: {
|
||||
'zh-CN': zhCN,
|
||||
},
|
||||
})
|
||||
const router = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [
|
||||
{ path: '/', component: { template: '<div />' } },
|
||||
{ path: '/reservation/orders/:orderId', component: { template: '<div />' } },
|
||||
{ path: '/reservation/tasks/:taskId', component: { template: '<div />' } },
|
||||
{ path: '/reservation/source-messages/:sourceMessageId/conversation', component: { template: '<div />' } },
|
||||
],
|
||||
})
|
||||
await router.push(initialPath)
|
||||
await router.isReady()
|
||||
|
||||
return mount(component, {
|
||||
global: {
|
||||
plugins: [i18n, router],
|
||||
stubs: {
|
||||
RouterLink: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
describe('reservation P0 views', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(service.fetchReservationOrders).mockReset()
|
||||
vi.mocked(service.fetchReservationTaskList).mockReset()
|
||||
vi.mocked(service.fetchSourceMessageConversation).mockReset()
|
||||
})
|
||||
|
||||
it('shows pending state for the order list endpoint', async () => {
|
||||
vi.mocked(service.fetchReservationOrders).mockRejectedValue(
|
||||
new EndpointPendingError('GET /api/reservation/orders is pending backend implementation.'),
|
||||
)
|
||||
|
||||
const wrapper = await mountWithPlugins(ReservationOrderListView)
|
||||
await vi.dynamicImportSettled()
|
||||
|
||||
expect(wrapper.text()).toContain('接口待接入')
|
||||
expect(wrapper.text()).not.toContain('#ORD-083')
|
||||
})
|
||||
|
||||
it('renders task list items returned by the backend', async () => {
|
||||
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createTaskListResult('GRP-001', 'Booking Request'))
|
||||
|
||||
const wrapper = await mountWithPlugins(ReservationTaskListView)
|
||||
await vi.dynamicImportSettled()
|
||||
|
||||
expect(wrapper.text()).toContain('GRP-001')
|
||||
expect(wrapper.text()).toContain('Booking Request')
|
||||
expect(wrapper.text()).toContain('接口待补')
|
||||
})
|
||||
|
||||
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>>>()
|
||||
vi.mocked(service.fetchReservationTaskList)
|
||||
.mockReturnValueOnce(firstRequest.promise)
|
||||
.mockReturnValueOnce(secondRequest.promise)
|
||||
|
||||
const wrapper = await mountWithPlugins(ReservationTaskListView)
|
||||
await wrapper.find('input[type="search"]').setValue('fresh')
|
||||
expect(service.fetchReservationTaskList).toHaveBeenCalledTimes(2)
|
||||
|
||||
secondRequest.resolve(createTaskListResult('GRP-NEW', 'New Booking Request'))
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('GRP-NEW')
|
||||
|
||||
firstRequest.resolve(createTaskListResult('GRP-OLD', 'Old Booking Request'))
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).toContain('GRP-NEW')
|
||||
expect(wrapper.text()).not.toContain('GRP-OLD')
|
||||
})
|
||||
|
||||
it('shows pending state for the source message conversation endpoint', async () => {
|
||||
vi.mocked(service.fetchSourceMessageConversation).mockRejectedValue(
|
||||
new EndpointPendingError('GET /api/source-messages/30001/conversation is pending backend implementation.'),
|
||||
)
|
||||
|
||||
const wrapper = await mountWithPlugins(
|
||||
ReservationSourceMessageConversationView,
|
||||
'/reservation/source-messages/30001/conversation',
|
||||
)
|
||||
await vi.dynamicImportSettled()
|
||||
|
||||
expect(service.fetchSourceMessageConversation).toHaveBeenCalledWith('30001')
|
||||
expect(wrapper.text()).toContain('接口待接入')
|
||||
expect(wrapper.text()).not.toContain('完整邮件正文')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user