接入M002V4订单任务多卡前端

This commit is contained in:
andy
2026-07-19 13:48:07 +07:00
parent 13364e7edf
commit cae169cefd
19 changed files with 4084 additions and 343 deletions

View File

@@ -10,7 +10,11 @@ import ReservationOrderListView from '@/views/reservation/ReservationOrderListVi
import ReservationSourceMessageConversationView from '@/views/reservation/ReservationSourceMessageConversationView.vue'
import ReservationTaskListView from '@/views/reservation/ReservationTaskListView.vue'
import { useAuthStore } from '@/stores/authStore'
import type { ReservationTaskListResult, SourceMessageConversationResult } from '@/types/reservation'
import type {
ReservationV4OrderTaskListResult,
ReservationV4WorkbenchListResult,
SourceMessageConversationResult,
} from '@/types/reservation'
vi.mock('@/services/reservationService', async (importOriginal) => {
const actual = await importOriginal<typeof import('@/services/reservationService')>()
@@ -19,6 +23,8 @@ vi.mock('@/services/reservationService', async (importOriginal) => {
fetchReservationOrderDetail: vi.fn(),
fetchReservationOrders: vi.fn(),
fetchReservationTaskList: vi.fn(),
fetchReservationV4OrderTasks: vi.fn(),
fetchReservationV4WorkbenchItems: vi.fn(),
fetchSourceMessageConversation: vi.fn(),
}
})
@@ -54,37 +60,47 @@ function createOrderListResult(
}
}
function createTaskListResult(
displayOrderKey: string,
sourceSubject: string,
function createV4WorkbenchResult(
displayOrderKey = 'GRP-001',
sourceSubject = 'Booking Request',
page: { page_num: number; page_size: number; total: number } = {
page_num: 1,
page_size: 20,
total: 1,
},
): ReservationTaskListResult {
): ReservationV4WorkbenchListResult {
return {
items: [
{
task_id: displayOrderKey === 'GRP-NEW' ? '10002' : '10001',
order_id: '20001',
item_type: 'ORDER_TASK',
target_id: displayOrderKey === 'GRP-NEW' ? '9002' : '9001',
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,
source_message_summary: {
source_message_id: '30001',
hotel_id: 'HOTEL-TEST',
external_message_id: 'msg-30001',
external_conversation_id: 'thread-30001',
subject: sourceSubject,
sender_summary: 'guest@example.test',
received_at: '2026-07-08T03:00:00Z',
source_sent_at: null,
conversation_message_count: 2,
},
source_received_at: '2026-07-08T03:00:00Z',
display_order_key: displayOrderKey,
card_counts: {
total_count: 3,
readonly_count: 1,
pending_confirm_count: 1,
review_required_count: 1,
confirmed_count: 0,
},
next_action_card_id: '9101',
notification_status: null,
order_task_status: 'OPEN',
display_status: 'OPEN',
readonly_reason_code: null,
created_at: '2026-07-08T03:00:00Z',
updated_at: '2026-07-08T03:10:00Z',
},
@@ -93,33 +109,33 @@ function createTaskListResult(
}
}
function createSourceMessageOnlyTaskListResult(taskSubtype: 'S10' | 'S99' = 'S10') {
function createV4SourceNotificationWorkbenchResult(routeCode: 'S10' | 'S99' = 'S10'): ReservationV4WorkbenchListResult {
return {
items: [
{
task_id: taskSubtype === 'S10' ? '19990' : '19999',
order_id: taskSubtype === 'S10' ? '29990' : '29999',
item_type: 'SOURCE_NOTIFICATION',
target_id: routeCode === 'S10' ? '7001' : '7002',
hotel_id: 'HOTEL-TEST',
display_order_key: null,
temporary_order_no: null,
task_type: 'MESSAGE_NOTIFICATION',
task_subtype: taskSubtype,
result_type: 'source_message_review_notification',
ai_task_type: 'Message Notification',
route_code: taskSubtype,
system_process_category: 'SOURCE_MESSAGE_NOTIFICATION',
task_status: 'COMPLETED',
card_name: 'Message Notification',
queue_sequence: null,
queue_participation: false,
can_process: false,
readonly_reason_code: 'QUEUE_EXCLUDED',
source_message_id: taskSubtype === 'S10' ? '39990' : '39999',
source_subject: taskSubtype === 'S10' ? 'FYI only' : 'Unclear email',
source_sender_summary: 'guest@example.test',
source_message_id: routeCode === 'S10' ? '39990' : '39999',
source_message_summary: {
source_message_id: routeCode === 'S10' ? '39990' : '39999',
hotel_id: 'HOTEL-TEST',
external_message_id: `msg-${routeCode}`,
external_conversation_id: 'thread-source-only',
subject: routeCode === 'S10' ? 'FYI only' : 'Unclear email',
sender_summary: 'guest@example.test',
received_at: '2026-07-08T03:00:00Z',
source_sent_at: null,
conversation_message_count: 1,
},
source_received_at: '2026-07-08T03:00:00Z',
external_conversation_id: 'thread-source-only',
conversation_message_count: 1,
display_order_key: null,
card_counts: null,
next_action_card_id: null,
notification_status: 'ACK_REQUIRED',
order_task_status: null,
display_status: 'ACK_REQUIRED',
readonly_reason_code: null,
created_at: '2026-07-08T03:00:00Z',
updated_at: '2026-07-08T03:10:00Z',
},
@@ -132,19 +148,73 @@ function createSourceMessageOnlyTaskListResult(taskSubtype: 'S10' | 'S99' = 'S10
}
}
function createParentGroupCancelAllotmentTaskListResult(): ReservationTaskListResult {
const result = createTaskListResult('PARENT-2608-BLOCK', 'Parent split confirmation')
result.items[0] = {
...result.items[0]!,
task_type: 'CANCEL_BOOKING',
task_subtype: 'cancel_allotment_control_block',
result_type: 'normal_task',
ai_task_type: 'Cancel Allotment',
route_code: 'R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL',
system_process_category: 'BUSINESS_TASK',
card_name: 'CANCEL_ALLOTMENT',
function createV4OrderTaskListResult(
displayOrderKey = 'GRP-002',
sourceSubject = 'Booking Update',
page: { page_num: number; page_size: number; total: number } = {
page_num: 1,
page_size: 20,
total: 1,
},
): ReservationV4OrderTaskListResult {
return {
items: [
{
order_task: {
order_task_id: displayOrderKey === 'GRP-NEW' ? '9002' : '9001',
hotel_id: 'HOTEL-TEST',
source_message_id: '30002',
ai_batch_id: '8001',
order_ref: 'order-1',
order_context_index: 1,
order_id: '20001',
target_booking_type: 'GROUP',
target_locator_type: 'GROUP_CODE',
target_locator_value: displayOrderKey,
target_resolution_status: 'RESOLVED',
order_task_status: 'OPEN',
display_order_key: displayOrderKey,
source_received_at: '2026-07-08T04:00:00Z',
version: 0,
created_at: '2026-07-08T04:00:00Z',
updated_at: '2026-07-08T04:10:00Z',
},
source_message_summary: {
source_message_id: '30002',
hotel_id: 'HOTEL-TEST',
external_message_id: 'msg-30002',
external_conversation_id: 'thread-30002',
subject: sourceSubject,
sender_summary: 'agent@example.test',
received_at: '2026-07-08T04:00:00Z',
source_sent_at: null,
conversation_message_count: 3,
},
card_counts: {
total_count: 2,
readonly_count: 1,
pending_confirm_count: 1,
review_required_count: 0,
confirmed_count: 0,
},
next_action_card_id: '9102',
display_status: 'OPEN',
availability: {
blocked: false,
read_only: false,
editable: true,
confirmable: true,
reviewable: false,
ackable: false,
readonly_reason_code: null,
blocked_by_order_task_id: null,
blocked_by_card_id: null,
blocked_reason: null,
},
},
],
page,
}
return result
}
function createOrderDetailResult(displayName = 'GRP-001') {
@@ -343,6 +413,8 @@ async function mountWithPlugins(component: object, initialPath = '/', stubs: Rec
{ path: '/', component: { template: '<div />' } },
{ path: '/reservation/orders/:orderId', component: { template: '<div />' } },
{ path: '/reservation/tasks/:taskId', component: { template: '<div />' } },
{ path: '/reservation/order-tasks/:orderTaskId', component: { template: '<div />' } },
{ path: '/reservation/source-notifications/:notificationId', component: { template: '<div />' } },
{ path: '/reservation/source-messages/:sourceMessageId/conversation', component: { template: '<div />' } },
],
})
@@ -369,6 +441,8 @@ describe('reservation P0 views', () => {
vi.mocked(service.fetchReservationOrderDetail).mockReset()
vi.mocked(service.fetchReservationOrders).mockReset()
vi.mocked(service.fetchReservationTaskList).mockReset()
vi.mocked(service.fetchReservationV4OrderTasks).mockReset()
vi.mocked(service.fetchReservationV4WorkbenchItems).mockReset()
vi.mocked(service.fetchSourceMessageConversation).mockReset()
})
@@ -483,209 +557,127 @@ describe('reservation P0 views', () => {
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'))
it('renders V4 workbench items returned by the backend', async () => {
vi.mocked(service.fetchReservationV4WorkbenchItems).mockResolvedValue(createV4WorkbenchResult('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('新预订')
expect(wrapper.text()).toContain('订单任务')
expect(wrapper.text()).toContain('待确认 1')
expect(wrapper.text()).toContain('待复核 1')
expect(wrapper.text()).toContain('查看邮件会话')
expect(wrapper.text()).not.toContain('接口待补')
expect(wrapper.text()).not.toContain('NEW_BOOKING / NEW_BOOKING')
expect(service.fetchReservationV4WorkbenchItems).toHaveBeenCalledWith(
expect.objectContaining({
page_num: 1,
page_size: 20,
}),
)
expect(service.fetchReservationTaskList).not.toHaveBeenCalled()
})
it('renders task source received time in the source email column', async () => {
const taskListResult = createTaskListResult('GRP-001', 'Booking Request')
taskListResult.items[0] = {
...taskListResult.items[0]!,
source_sender_summary: 'guest@example.test',
source_received_at: '2026-07-08T03:00:00Z',
}
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(taskListResult)
vi.mocked(service.fetchReservationV4WorkbenchItems).mockResolvedValue(createV4WorkbenchResult('GRP-001', 'Booking Request'))
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
expect(wrapper.text()).toContain('来源时间')
expect(wrapper.text()).toContain('2026-07-08 10:00:00')
expect(wrapper.text()).toContain('guest@example.test')
})
it('filters source-message-only tasks with S10 and S99 subtypes', async () => {
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createSourceMessageOnlyTaskListResult('S10'))
it('renders V4 S10/S99 source notification rows without a visible order action', async () => {
vi.mocked(service.fetchReservationV4WorkbenchItems).mockResolvedValue(createV4SourceNotificationWorkbenchResult('S10'))
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
const taskTypeOptions = wrapper.find('select[name="task_type"]').findAll('option')
.map((option) => option.attributes('value'))
const taskSubtypeOptions = wrapper.find('select[name="task_subtype"]').findAll('option')
.map((option) => option.attributes('value'))
expect(wrapper.text()).toContain('FYI only')
expect(wrapper.text()).toContain('来源通知')
expect(wrapper.text()).toContain('待确认已读')
expect(wrapper.text()).toContain('查看通知')
expect(wrapper.text()).toContain('查看邮件会话')
expect(wrapper.text()).not.toContain('查看订单')
})
expect(taskTypeOptions).toEqual([
'',
'NEW_BOOKING',
'UPDATE_BOOKING',
'CANCEL_BOOKING',
'MANUAL_REVIEW',
'SOURCE_MESSAGE_ONLY',
])
expect(taskTypeOptions).not.toContain('INFORMATIONAL_MESSAGE')
expect(taskSubtypeOptions).toEqual([
'',
'NEW_BOOKING',
'UPDATE_BOOKING',
'CANCEL_BOOKING',
'RATE_CHANGE',
'UPDATE_STAY_DATES',
'UPDATE_ROOM_TYPE',
'UPDATE_FIX_CHARGE',
'NEW_GROUP_BLOCK',
'NEW_FIT_RESERVATION',
'MANUAL_REVIEW',
'S10',
'S99',
])
expect(taskSubtypeOptions).not.toContain('S000')
expect(taskSubtypeOptions).not.toContain('S999')
expect(taskSubtypeOptions).not.toContain('linked_parent_release_after_child_split')
expect(wrapper.find('select[name="task_type"]').text()).toContain('来源消息只读')
expect(wrapper.find('select[name="task_subtype"]').text()).toContain('纯信息类邮件S10')
expect(wrapper.find('select[name="task_subtype"]').text()).toContain('无法形成业务素材包S99')
it('filters V4 workbench with supported backend fields only', async () => {
vi.mocked(service.fetchReservationV4WorkbenchItems)
.mockResolvedValueOnce(createV4WorkbenchResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createV4SourceNotificationWorkbenchResult('S10'))
await wrapper.find('select[name="task_type"]').setValue('SOURCE_MESSAGE_ONLY')
await vi.dynamicImportSettled()
await wrapper.find('select[name="task_subtype"]').setValue('S99')
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
expect(service.fetchReservationTaskList).toHaveBeenLastCalledWith(
const itemTypeOptions = wrapper.find('select[name="item_type"]').findAll('option')
.map((option) => option.attributes('value'))
expect(itemTypeOptions).toEqual(['', 'ORDER_TASK', 'SOURCE_NOTIFICATION'])
expect(wrapper.find('select[name="item_type"]').text()).toContain('来源通知')
expect(wrapper.find('select[name="item_type"]').text()).not.toContain('INFORMATIONAL_MESSAGE')
await wrapper.find('select[name="item_type"]').setValue('SOURCE_NOTIFICATION')
await vi.dynamicImportSettled()
expect(service.fetchReservationV4WorkbenchItems).toHaveBeenLastCalledWith(
expect.objectContaining({
task_type: 'SOURCE_MESSAGE_ONLY',
task_subtype: 'S99',
item_type: 'SOURCE_NOTIFICATION',
page_num: 1,
}),
)
const lastTaskRequest = vi.mocked(service.fetchReservationTaskList).mock.calls[
vi.mocked(service.fetchReservationTaskList).mock.calls.length - 1
const lastTaskRequest = vi.mocked(service.fetchReservationV4WorkbenchItems).mock.calls[
vi.mocked(service.fetchReservationV4WorkbenchItems).mock.calls.length - 1
]?.[0] ?? {}
expect(Object.keys(lastTaskRequest).sort()).toEqual([
'keyword',
'order_status',
'page_num',
'page_size',
'queue_participation',
'task_status',
'task_subtype',
'task_type',
])
expect(Object.keys(lastTaskRequest).sort()).toEqual(['item_type', 'keyword', 'page_num', 'page_size'])
expect(lastTaskRequest).not.toHaveProperty('task_type')
expect(lastTaskRequest).not.toHaveProperty('task_subtype')
expect(lastTaskRequest).not.toHaveProperty('result_type')
expect(lastTaskRequest).not.toHaveProperty('route_code')
expect(lastTaskRequest).not.toHaveProperty('system_process_category')
})
it('renders R08 parent group cancel allotment as a business card', async () => {
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createParentGroupCancelAllotmentTaskListResult())
it('filters and paginates V4 business order tasks with supported backend fields', async () => {
vi.mocked(service.fetchReservationV4WorkbenchItems)
.mockResolvedValueOnce(createV4WorkbenchResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
vi.mocked(service.fetchReservationV4OrderTasks)
.mockResolvedValueOnce(createV4OrderTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createV4OrderTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createV4OrderTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createV4OrderTaskListResult('GRP-002', 'Booking Update', { page_num: 2, page_size: 20, total: 45 }))
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
expect(wrapper.text()).toContain('PARENT-2608-BLOCK')
expect(wrapper.text()).toContain('Parent Group')
expect(wrapper.text()).toContain('取消 Parent Group 配额')
expect(wrapper.text()).toContain('取消 Parent Group 整块配额')
expect(wrapper.text()).toContain('查看订单')
expect(wrapper.text()).not.toContain('适配契约异常')
expect(wrapper.text()).not.toContain('linked_parent_release_after_child_split')
})
expect(wrapper.find('select[name="order_task_status"]').attributes('disabled')).toBeDefined()
expect(wrapper.find('select[name="card_status"]').attributes('disabled')).toBeDefined()
it('renders source-message-only task rows without a visible order action', async () => {
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(createSourceMessageOnlyTaskListResult('S10'))
await wrapper.find('select[name="item_type"]').setValue('ORDER_TASK')
await vi.dynamicImportSettled()
expect(wrapper.find('select[name="order_task_status"]').attributes('disabled')).toBeUndefined()
expect(wrapper.find('select[name="card_status"]').attributes('disabled')).toBeUndefined()
const wrapper = await mountWithPlugins(ReservationTaskListView)
await wrapper.find('select[name="order_task_status"]').setValue('OPEN')
await vi.dynamicImportSettled()
await wrapper.find('select[name="card_status"]').setValue('REVIEW_REQUIRED')
await vi.dynamicImportSettled()
expect(wrapper.text()).toContain('来源消息只读')
expect(wrapper.text()).toContain('纯信息类邮件S10')
expect(wrapper.text()).toContain('来源消息通知')
expect(wrapper.text()).toContain('FYI only')
expect(wrapper.text()).toContain('查看任务')
expect(wrapper.text()).toContain('查看邮件会话')
expect(wrapper.text()).not.toContain('查看订单')
expect(wrapper.text()).not.toContain('29990')
})
it('does not treat a business task as source-message-only only because subtype is S10', async () => {
const result = createTaskListResult('GRP-S10-BUSINESS', 'Business booking request')
result.items[0] = {
...result.items[0]!,
task_type: 'NEW_BOOKING',
task_subtype: 'S10',
result_type: 'normal_task',
ai_task_type: 'NEW_BOOKING',
route_code: 'S10',
system_process_category: 'BUSINESS_TASK',
card_name: 'New Booking',
}
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(result)
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
const rowText = wrapper.find('tbody').text()
expect(rowText).toContain('GRP-S10-BUSINESS')
expect(rowText).toContain('20001')
expect(rowText).toContain('查看订单')
expect(rowText).not.toContain('来源消息只读')
expect(rowText).not.toContain('不关联可见订单')
})
it('filters and paginates task list with supported backend fields', async () => {
vi.mocked(service.fetchReservationTaskList)
.mockResolvedValueOnce(createTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createTaskListResult('GRP-001', 'Booking Request', { page_num: 1, page_size: 20, total: 45 }))
.mockResolvedValueOnce(createTaskListResult('GRP-002', 'Booking Update', { page_num: 2, page_size: 20, total: 45 }))
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
expect(wrapper.text()).not.toContain('订单状态筛选待后端接入')
expect(wrapper.find('select[name="order_status"]').attributes('disabled')).toBeUndefined()
expect(wrapper.find('select[name="task_status"]').text()).toContain('执行中')
expect(wrapper.find('select[name="task_status"]').text()).toContain('失败')
await wrapper.find('select[name="task_status"]').setValue('FAILED')
await vi.dynamicImportSettled()
await wrapper.find('select[name="task_subtype"]').setValue('RATE_CHANGE')
await vi.dynamicImportSettled()
await wrapper.find('select[name="order_status"]').setValue('ENDED')
await vi.dynamicImportSettled()
await wrapper.find('select[name="queue_participation"]').setValue('true')
await vi.dynamicImportSettled()
const taskListCalls = vi.mocked(service.fetchReservationTaskList).mock.calls
const taskListCalls = vi.mocked(service.fetchReservationV4OrderTasks).mock.calls
const filteredTaskRequest = taskListCalls[taskListCalls.length - 1]?.[0] ?? {}
expect(filteredTaskRequest).toMatchObject({
task_status: 'FAILED',
task_subtype: 'RATE_CHANGE',
order_status: 'ENDED',
queue_participation: true,
order_task_status: 'OPEN',
card_status: 'REVIEW_REQUIRED',
page_num: 1,
})
await wrapper.findAll('button').find((button) => button.text().includes('下一页'))?.trigger('click')
await vi.dynamicImportSettled()
expect(service.fetchReservationTaskList).toHaveBeenLastCalledWith(
expect(service.fetchReservationV4OrderTasks).toHaveBeenLastCalledWith(
expect.objectContaining({
task_status: 'FAILED',
task_subtype: 'RATE_CHANGE',
order_status: 'ENDED',
queue_participation: true,
order_task_status: 'OPEN',
card_status: 'REVIEW_REQUIRED',
page_num: 2,
page_size: 20,
}),
@@ -695,8 +687,8 @@ describe('reservation P0 views', () => {
})
it('renders backend-normalized task pagination metadata', async () => {
vi.mocked(service.fetchReservationTaskList).mockResolvedValue(
createTaskListResult('GRP-001', 'Booking Request', { page_num: 2, page_size: 10, total: 21 }),
vi.mocked(service.fetchReservationV4WorkbenchItems).mockResolvedValue(
createV4WorkbenchResult('GRP-001', 'Booking Request', { page_num: 2, page_size: 10, total: 21 }),
)
const wrapper = await mountWithPlugins(ReservationTaskListView)
@@ -706,9 +698,9 @@ describe('reservation P0 views', () => {
})
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'))
vi.mocked(service.fetchReservationV4WorkbenchItems)
.mockResolvedValueOnce(createV4WorkbenchResult('GRP-001', 'Booking Request'))
.mockResolvedValueOnce(createV4WorkbenchResult('GRP-002', 'Booking Update'))
const wrapper = await mountWithPlugins(ReservationTaskListView)
await vi.dynamicImportSettled()
@@ -717,8 +709,8 @@ describe('reservation P0 views', () => {
authStore.setSelectedHotelId('HOTEL-BKK')
await vi.dynamicImportSettled()
expect(service.fetchReservationTaskList).toHaveBeenCalledTimes(2)
expect(service.fetchReservationTaskList).toHaveBeenLastCalledWith(
expect(service.fetchReservationV4WorkbenchItems).toHaveBeenCalledTimes(2)
expect(service.fetchReservationV4WorkbenchItems).toHaveBeenLastCalledWith(
expect.objectContaining({
page_num: 1,
}),
@@ -748,21 +740,21 @@ describe('reservation P0 views', () => {
})
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)
const firstRequest = createDeferred<Awaited<ReturnType<typeof service.fetchReservationV4WorkbenchItems>>>()
const secondRequest = createDeferred<Awaited<ReturnType<typeof service.fetchReservationV4WorkbenchItems>>>()
vi.mocked(service.fetchReservationV4WorkbenchItems)
.mockReturnValueOnce(firstRequest.promise)
.mockReturnValueOnce(secondRequest.promise)
const wrapper = await mountWithPlugins(ReservationTaskListView)
await wrapper.find('input[type="search"]').setValue('fresh')
expect(service.fetchReservationTaskList).toHaveBeenCalledTimes(2)
expect(service.fetchReservationV4WorkbenchItems).toHaveBeenCalledTimes(2)
secondRequest.resolve(createTaskListResult('GRP-NEW', 'New Booking Request'))
secondRequest.resolve(createV4WorkbenchResult('GRP-NEW', 'New Booking Request'))
await flushPromises()
expect(wrapper.text()).toContain('GRP-NEW')
firstRequest.resolve(createTaskListResult('GRP-OLD', 'Old Booking Request'))
firstRequest.resolve(createV4WorkbenchResult('GRP-OLD', 'Old Booking Request'))
await flushPromises()
expect(wrapper.text()).toContain('GRP-NEW')
expect(wrapper.text()).not.toContain('GRP-OLD')