feat(reservation): solidify booking email v0.1 intake
This commit is contained in:
1 parent
9f29b59c26
commit
d91cd717df
61 files changed
+13961
-377
No files matched your search
@@ -0,0 +1,163 @@
|
||||
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 type { BookingProcessingRunView } from '@/types/bookingContracts'
|
||||
import ReservationBookingProcessingRunView from '@/views/reservation/ReservationBookingProcessingRunView.vue'
|
||||
|
||||
vi.mock('@/services/reservationService', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@/services/reservationService')>()
|
||||
return {
|
||||
...actual,
|
||||
fetchBookingProcessingRun: vi.fn(),
|
||||
confirmBookingProcessingRun: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
const service = await import('@/services/reservationService')
|
||||
|
||||
describe('ReservationBookingProcessingRunView', () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(service.fetchBookingProcessingRun).mockReset()
|
||||
vi.mocked(service.confirmBookingProcessingRun).mockReset()
|
||||
})
|
||||
|
||||
it('shows the safe confirmation projection and freezes corrected values without a PMS action', async () => {
|
||||
const initial = awaitingRun()
|
||||
const confirmed = {
|
||||
...initial,
|
||||
status: 'CONFIRMED' as const,
|
||||
confirmation_projection: {
|
||||
...initial.confirmation_projection!,
|
||||
projection_status: 'AWAITING_CONFIRMATION' as const,
|
||||
processing_status: 'CONFIRMED' as const,
|
||||
},
|
||||
}
|
||||
vi.mocked(service.fetchBookingProcessingRun).mockResolvedValue(initial)
|
||||
vi.mocked(service.confirmBookingProcessingRun).mockResolvedValue({
|
||||
confirmed: true,
|
||||
processing_run: confirmed,
|
||||
})
|
||||
const wrapper = await mountView()
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.text()).toContain('等待确认')
|
||||
expect(wrapper.text()).toContain('RATE_CODE_REQUIRED')
|
||||
await wrapper.find('select').setValue('FIT')
|
||||
await wrapper.find('input[type="text"]').setValue('QBD-850')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
await flushPromises()
|
||||
|
||||
expect(service.confirmBookingProcessingRun).toHaveBeenCalledWith('booking-001', {
|
||||
items: [
|
||||
{
|
||||
confirmation_item_id: 'confirmation-fact-1',
|
||||
field_overrides: {
|
||||
booking_type: 'FIT',
|
||||
rate_code: 'QBD-850',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
expect(wrapper.text()).toContain('参数已冻结')
|
||||
expect(wrapper.text()).toContain('已确认')
|
||||
})
|
||||
})
|
||||
|
||||
async function mountView() {
|
||||
const router = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/reservation/booking-processing-runs/:runId',
|
||||
component: ReservationBookingProcessingRunView,
|
||||
},
|
||||
{ path: '/reservation/email-intake', component: { template: '<div>Intake</div>' } },
|
||||
],
|
||||
})
|
||||
await router.push('/reservation/booking-processing-runs/booking-001')
|
||||
await router.isReady()
|
||||
return mount(ReservationBookingProcessingRunView, {
|
||||
global: {
|
||||
plugins: [
|
||||
router,
|
||||
createI18n({
|
||||
legacy: false,
|
||||
locale: 'zh-CN',
|
||||
messages: { 'zh-CN': zhCN },
|
||||
}),
|
||||
],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function awaitingRun(): BookingProcessingRunView {
|
||||
return {
|
||||
processing_run_id: 'booking-001',
|
||||
source_message_id: 'manual-eml-001',
|
||||
revision_number: 1,
|
||||
status: 'AWAITING_CONFIRMATION',
|
||||
result_disposition: 'IN_SCOPE_TASKS',
|
||||
duplicate: false,
|
||||
retry_count: 0,
|
||||
error_code: null,
|
||||
error_summary: null,
|
||||
started_at: '2026-08-08T00:00:00Z',
|
||||
completed_at: null,
|
||||
confirmation_projection: {
|
||||
contract_meta: {
|
||||
contract_version: 'booking-contracts-v1',
|
||||
catalog_version: 'booking-catalog-v20260808',
|
||||
parser_version: 'booking-email-parser-v0.1',
|
||||
agent_profile_version: 'agent-not-invoked',
|
||||
processing_run_id: 'booking-001',
|
||||
source_message_id: 'manual-eml-001',
|
||||
source_revision: 0,
|
||||
},
|
||||
evidence_refs: [],
|
||||
projection_status: 'REVIEW_REQUIRED',
|
||||
confirmation_items: [
|
||||
{
|
||||
confirmation_item_id: 'confirmation-fact-1',
|
||||
target_decision_id: 'fact-1',
|
||||
disposition: 'IN_SCOPE_TASKS',
|
||||
display_fields: [
|
||||
{
|
||||
field_code: 'booking_type',
|
||||
value: null,
|
||||
editable: true,
|
||||
allowed_values: ['FIT', 'GROUP'],
|
||||
evidence_refs: [],
|
||||
issues: [],
|
||||
},
|
||||
],
|
||||
blocked_fields: [
|
||||
{
|
||||
field_code: 'rate_code',
|
||||
value: null,
|
||||
editable: true,
|
||||
allowed_values: [],
|
||||
evidence_refs: [],
|
||||
issues: [
|
||||
{
|
||||
code: 'RATE_CODE_REQUIRED',
|
||||
severity: 'BLOCKER',
|
||||
scope: 'FIELD',
|
||||
message_key: 'booking.validator.rate_code_required',
|
||||
evidence_refs: [],
|
||||
retryable: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
linked_actions: [],
|
||||
safe_evidence_refs: [],
|
||||
},
|
||||
],
|
||||
issues: [],
|
||||
processing_status: 'AWAITING_CONFIRMATION',
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user