优化预订事项卡片布局

This commit is contained in:
andy
2026-07-22 10:12:20 +07:00
parent 434afeb7c5
commit 08c8b0165b
3 changed files with 437 additions and 111 deletions

View File

@@ -1,4 +1,5 @@
import { flushPromises, mount } from '@vue/test-utils'
import type { DOMWrapper } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import PrimeVue from 'primevue/config'
import { beforeEach, describe, expect, it, vi } from 'vitest'
@@ -38,6 +39,10 @@ vi.mock('@/services/reservationService', async (importOriginal) => {
const service = await import('@/services/reservationService')
function findFieldByLabel(wrapper: DOMWrapper<Element>, label: string): DOMWrapper<Element> | undefined {
return wrapper.findAll('.v4-field').find((field) => field.find('.v4-field__label').text().includes(label))
}
describe('reservation V4 pages', () => {
beforeEach(() => {
sessionStorage.clear()
@@ -125,7 +130,7 @@ describe('reservation V4 pages', () => {
})
})
it('keeps task card layout classes and places the primary card action in the card header', async () => {
it('keeps task card layout classes and places the primary card action in the card footer', async () => {
const detail = createOrderTaskDetail()
detail.business_cards[0]!.card_type = 'VOUCHER'
detail.business_cards[0]!.display_payload = {
@@ -144,7 +149,13 @@ describe('reservation V4 pages', () => {
expect(wrapper.find('.task-card-section__header').exists()).toBe(true)
expect(wrapper.find('.card-meta-grid').exists()).toBe(false)
expect(wrapper.find('details.safe-payload').exists()).toBe(false)
expect(wrapper.find('.task-card-section__header .primary-button').text()).toContain(zhCN.taskV4.confirmCard)
expect(wrapper.find('.task-card-section__header .primary-button').exists()).toBe(false)
const firstCard = wrapper.find('.task-card-section')
const footer = firstCard.find('.task-card-section__footer')
expect(footer.exists()).toBe(true)
const cardChildren = Array.from(firstCard.element.children)
expect(cardChildren[cardChildren.length - 1]).toBe(footer.element)
expect(footer.find('.task-card-section__footer-actions .primary-button').text()).toContain(zhCN.taskV4.confirmCard)
expect(wrapper.find('.card-actions .primary-button').exists()).toBe(false)
})
@@ -758,6 +769,26 @@ describe('reservation V4 pages', () => {
value: 'LEGACY',
}),
]
const groupStatusField = detail.business_cards[0]!.fields.find((field) =>
field.field_pointer === '/room_information/final_values/group_booking_status',
)
if (groupStatusField) {
groupStatusField.validation_errors = ['请选择团队预订状态']
groupStatusField.fixed_options = [
{
value: 'TEN',
label: 'TEN-Tentative',
},
{
value: 'DEF',
label: 'DEF-Definite',
},
{
value: 'INQ',
label: 'INQ-Inquiry',
},
]
}
vi.mocked(service.fetchReservationV4OrderTaskDetail).mockResolvedValue(detail)
vi.mocked(service.confirmReservationV4OrderTaskCard).mockResolvedValue({
...detail,
@@ -780,6 +811,22 @@ describe('reservation V4 pages', () => {
expect(roomCard.text()).toContain(zhCN.taskV4.roomInformation.finalValues)
expect(roomCard.text()).toContain('TEN-Tentative')
expect(roomCard.text()).toContain('3')
expect(roomCard.text()).toContain(zhCN.taskV4.roomInformation.confirmationNumber)
expect(roomCard.text()).toContain(zhCN.taskV4.roomInformation.blockId)
const confirmationField = findFieldByLabel(roomCard, zhCN.taskV4.roomInformation.confirmationNumber)
const blockIdField = findFieldByLabel(roomCard, zhCN.taskV4.roomInformation.blockId)
expect(confirmationField?.find('.v4-field__static').text()).toBe('-')
expect(blockIdField?.find('.v4-field__static').text()).toBe('-')
const statusSlot = roomCard.find('.room-information__status-slot')
const statusSelect = statusSlot.find('select[name="/room_information/final_values/group_booking_status"]')
expect(statusSlot.text()).toContain(zhCN.taskV4.roomInformation.groupBookingStatus)
expect(statusSlot.text()).toContain('*')
expect(statusSlot.text()).toContain('TEN-Tentative')
expect(statusSelect.attributes('aria-invalid')).toBe('true')
expect(statusSelect.findAll('option').map((option) => (option.element as HTMLOptionElement).value))
.toEqual(['', 'TEN', 'DEF', 'INQ'])
expect(roomCard.find('.room-information__status-error').text()).toContain('请选择团队预订状态')
expect(roomCard.find('.room-information__derived').exists()).toBe(false)
expect(roomCard.text()).not.toContain('target_order')
expect(roomCard.text()).not.toContain('Adult')
expect(roomCard.text()).not.toContain('Legacy Room Type')
@@ -801,6 +848,13 @@ describe('reservation V4 pages', () => {
expect(roomCard.find('input[name="/room_information/final_values/departure_date"]').attributes('type')).toBe('text')
expect((roomCard.find('input[name="/room_information/final_values/departure_date"]').element as HTMLInputElement).value)
.toBe('2026-07-29')
const roomInformationText = roomCard.text()
expect(roomInformationText.indexOf(zhCN.taskV4.roomInformation.departureDate))
.toBeLessThan(roomInformationText.indexOf(zhCN.taskV4.roomInformation.nights))
expect(roomInformationText.indexOf(zhCN.taskV4.roomInformation.nights))
.toBeLessThan(roomInformationText.indexOf(zhCN.taskV4.roomInformation.rateCode))
expect(roomInformationText.indexOf(zhCN.taskV4.roomInformation.blockId))
.toBeLessThan(roomInformationText.indexOf(zhCN.taskV4.roomInformation.breakfastIncluded))
await roomCard.find('input[name="/room_information/final_values/group_block_name"]').setValue('前端修正团队名')
await roomCard.find('select[name="/room_information/final_values/group_booking_status"]').setValue('DEF')
@@ -1303,9 +1357,10 @@ describe('reservation V4 pages', () => {
it('keeps the per-card primary action right aligned on narrow screens', () => {
expect(taskCardSectionSource).toContain('@media (max-width: 980px)')
expect(taskCardSectionSource).toContain('.task-card-section__status-actions')
expect(taskCardSectionSource).toContain('align-self: stretch')
expect(taskCardSectionSource).toContain('.task-card-section__footer-actions')
expect(taskCardSectionSource).toContain('padding: 0 20px 20px')
expect(taskCardSectionSource).toContain('justify-content: flex-end')
expect(taskCardSectionSource).toContain('.task-card-section__footer {\n align-items: flex-end;\n }')
})
it('requires confirmed order id before resolving an unresolved V4 review card', async () => {