59 lines
4.6 KiB
TypeScript
59 lines
4.6 KiB
TypeScript
import ElementPlus, { ElMessageBox } from 'element-plus'
|
|||
|
|
import { createPinia } from 'pinia'
|
||
|
|
import { mount, flushPromises, type VueWrapper } from '@vue/test-utils'
|
||
|
|
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
|
||
|
|
import CapacityInquiryDialog from './CapacityInquiryDialog.vue'
|
||
|
|
import CapacityOfferSettingsDialog from './CapacityOfferSettingsDialog.vue'
|
||
|
|
import type { CapacityOffer } from '../capacityOfferTypes'
|
||
|
|
import type { FleetTrip } from '../tripTypes'
|
||
|
|
import { useUnsavedWorkStore } from '@/core/unsaved-work/unsavedWork'
|
||
|
|
import { listCapacityOffers } from '../api/capacityOffers'
|
||
|
|
|
||
|
|
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: () => true }) }))
|
||
|
|
vi.mock('../api/capacityOffers', () => ({ listCapacityOffers: vi.fn(), listOfferCustomers: vi.fn(), listOfferQuotes: vi.fn(), saveCapacityInquiry: vi.fn(), saveCapacityOffer: vi.fn(), commandCapacityOffer: vi.fn() }))
|
||
|
|
const offer: CapacityOffer = { offerNo: 'CO-CLOSE', tripNo: 'TR-CLOSE', status: 'OPEN', recordVersion: 1, tripRecordVersion: 2, warehouseId: '9', warehouseName: '测试仓', plannedDepartureAt: '2026-10-20T12:00:00Z', cutoffAt: '2026-10-20T10:00:00Z', contactName: null, contactPhone: null, remark: null, destinations: [{ destinationKey: 'FBA:ONT8', name: 'ONT8', deliveryIndex: 1, remaining: null }], segments: [], capacityKnown: false, canCreateInquiry: true, canConfirm: false, blockReason: '待核对', actions: { canEdit: true, canPublish: false, canPause: true, canResume: false, canClose: true } }
|
||
|
|
const wrappers: VueWrapper[] = []
|
||
|
|
beforeEach(() => { vi.clearAllMocks(); vi.mocked(listCapacityOffers).mockResolvedValue({ records: [offer], total: 1, page: 1, size: 1, pages: 1 }) })
|
||
|
|
afterEach(async () => { ElMessageBox.close(); wrappers.splice(0).forEach(wrapper => wrapper.unmount()); await flushPromises(); document.body.innerHTML = '' })
|
||
|
|
function mountDialog(kind: 'inquiry' | 'settings') {
|
||
|
|
const pinia = createPinia()
|
||
|
|
const wrapper = kind === 'inquiry'
|
||
|
|
? mount(CapacityInquiryDialog, { attachTo: document.body, props: { modelValue: true, offer, inquiry: null, readonly: false }, global: { plugins: [pinia, ElementPlus] } })
|
||
|
|
: mount(CapacityOfferSettingsDialog, { attachTo: document.body, props: { modelValue: false, trip: { tripNo: offer.tripNo, recordVersion: 2 } as FleetTrip }, global: { plugins: [pinia, ElementPlus] } })
|
||
|
|
wrappers.push(wrapper)
|
||
|
|
return { wrapper, pinia }
|
||
|
|
}
|
||
|
|
async function continueEditing() {
|
||
|
|
const message = [...document.querySelectorAll('.el-message-box')].at(-1)!
|
||
|
|
expect(message).not.toBeNull()
|
||
|
|
const button = [...message.querySelectorAll('button')].find(node => node.textContent?.trim() === '继续填写')!
|
||
|
|
expect(button).toBeTruthy(); button.click(); await flushPromises()
|
||
|
|
await new Promise(resolve => setTimeout(resolve, 50)); await flushPromises()
|
||
|
|
}
|
||
|
|
it.each(['inquiry', 'settings'] as const)('keeps the real %s dialog and edited input visible through cancel, Escape and X vetoes', async kind => {
|
||
|
|
const { wrapper, pinia } = mountDialog(kind)
|
||
|
|
if (kind === 'settings') await wrapper.setProps({ modelValue: true })
|
||
|
|
await flushPromises()
|
||
|
|
const input = wrapper.find<HTMLInputElement>(kind === 'inquiry' ? 'input[placeholder="选填"]' : 'input[placeholder="填写公开给销售的联系人(选填)"]')
|
||
|
|
expect(input.exists()).toBe(true)
|
||
|
|
await input.setValue('UI-未保存检查'); await flushPromises()
|
||
|
|
const assertPreserved = () => {
|
||
|
|
expect(wrapper.find('.app-dialog').isVisible()).toBe(true)
|
||
|
|
expect(input.element.isConnected).toBe(true)
|
||
|
|
expect(input.element.value).toBe('UI-未保存检查')
|
||
|
|
expect(wrapper.emitted('update:modelValue')).toBeUndefined()
|
||
|
|
expect(useUnsavedWorkStore(pinia).findBlocking(new Set(), true)).toHaveLength(1)
|
||
|
|
}
|
||
|
|
await wrapper.findAll('.app-dialog__footer button').find(button => button.text() === '取消')!.trigger('click'); await flushPromises()
|
||
|
|
assertPreserved(); await continueEditing(); assertPreserved()
|
||
|
|
input.element.focus(); await input.trigger('keydown', { key: 'Escape', code: 'Escape' }); await flushPromises()
|
||
|
|
assertPreserved(); await continueEditing(); assertPreserved()
|
||
|
|
await wrapper.get('.el-dialog__headerbtn').trigger('click'); await flushPromises()
|
||
|
|
assertPreserved(); await continueEditing(); assertPreserved()
|
||
|
|
await wrapper.findAll('.app-dialog__footer button').find(button => button.text() === '取消')!.trigger('click'); await flushPromises()
|
||
|
|
const message = [...document.querySelectorAll('.el-message-box')].at(-1)!
|
||
|
|
const accept = [...message.querySelectorAll('button')].find(button => button.textContent?.trim() === '确认关闭') as HTMLButtonElement
|
||
|
|
accept.click(); await flushPromises()
|
||
|
|
expect(wrapper.emitted('update:modelValue')).toEqual([[false]])
|
||
|
|
})
|