import { mount, flushPromises } from '@vue/test-utils';
|
import { beforeEach, expect, it, vi } from 'vitest';
|
const mocks = vi.hoisted(() => ({ on: vi.fn(), off: vi.fn(), cancel: vi.fn(), refresh: vi.fn(), resume: vi.fn() }));
|
vi.mock('#/utils/jnpf', () => ({ onlineUtils: { getEmitter: () => ({ on: mocks.on, off: mocks.off }) } }));
|
vi.mock('../dmsReprint', () => ({
|
REPRINT_LOCK_EVENT: 'lock',
|
REPRINT_COMPLETED_EVENT: 'completed',
|
cancelDmsReprint: mocks.cancel,
|
refreshDmsReprintLock: mocks.refresh,
|
resumeDmsReprint: mocks.resume,
|
}));
|
vi.mock('@jnpf/ui/modal', () => ({ BasicModal: { props: ['open'], template: '<div v-if="open"><slot/><slot name="footer"/></div>' } }));
|
vi.mock('ant-design-vue', () => ({
|
Button: { props: ['disabled'], template: '<button :disabled="disabled"><slot/></button>' },
|
Alert: { props: ['message'], template: '<div>{{message}}</div>' },
|
Spin: { template: '<div><slot/></div>' },
|
Descriptions: { template: '<div><slot/></div>' },
|
DescriptionsItem: { template: '<div><slot/></div>' },
|
}));
|
import Modal from '../DmsReprintStatusModal.vue';
|
const base = { locked: true, printRecordId: 'copy', requestId: 'request', owner: true, phase: 'READY', canCancel: true, canResume: true };
|
async function open(status = base) {
|
const wrapper = mount(Modal);
|
mocks.on.mock.calls.find(([name]) => name === 'lock');
|
await flushPromises();
|
return wrapper;
|
}
|
async function click(wrapper: ReturnType<typeof mount>, label: string) {
|
await wrapper
|
.findAll('button')
|
.find((b) => b.text() === label)!
|
.trigger('click');
|
await flushPromises();
|
}
|
beforeEach(() => vi.resetAllMocks());
|
it('shows another owner without cancellation or resume', async () => {
|
const w = await open({ ...base, owner: false, canCancel: false, canResume: false });
|
expect(w.text()).toContain('原发起人');
|
expect(w.text()).not.toContain('取消重打并解除锁定');
|
expect(w.text()).not.toContain('继续重打');
|
w.unmount();
|
expect(mocks.off).toHaveBeenCalled();
|
});
|
it('unknown results only allow refreshing receipts', async () => {
|
const w = await open({ ...base, phase: 'UNKNOWN', canCancel: false, canResume: false });
|
expect(w.text()).toContain('不能取消或重复打印');
|
expect(w.text()).not.toContain('确认取消');
|
w.unmount();
|
});
|
it('requires inline confirmation and preserves lock after rejected cancellation', async () => {
|
mocks.cancel.mockRejectedValue(new Error('任务已派发'));
|
const w = await open();
|
await click(w, '取消重打并解除锁定');
|
expect(mocks.cancel).not.toHaveBeenCalled();
|
await click(w, '确认取消');
|
expect(w.text()).toContain('任务已派发');
|
expect(mocks.refresh).not.toHaveBeenCalled();
|
expect(mocks.resume).not.toHaveBeenCalled();
|
w.unmount();
|
});
|
it('disables actions during cancellation and refreshes on success', async () => {
|
let resolve!: () => void;
|
mocks.cancel.mockReturnValue(new Promise<void>((r) => (resolve = r)));
|
mocks.refresh.mockResolvedValue({ ...base, locked: false, canResume: false, canCancel: false });
|
const w = await open();
|
await click(w, '取消重打并解除锁定');
|
await click(w, '确认取消');
|
expect(w.findAll('button').every((b) => b.attributes('disabled') !== undefined)).toBe(true);
|
resolve();
|
await flushPromises();
|
expect(w.text()).toContain('占用已解除');
|
expect(mocks.resume).not.toHaveBeenCalled();
|
w.unmount();
|
});
|
it('offers registration recovery for confirmed submission', async () => {
|
mocks.resume.mockResolvedValue(undefined);
|
const w = await open({ ...base, phase: 'REGISTRATION_PENDING', canCancel: false });
|
await click(w, '补登记');
|
expect(mocks.resume).toHaveBeenCalledWith('copy', 'request', undefined, undefined, undefined);
|
expect(mocks.cancel).not.toHaveBeenCalled();
|
w.unmount();
|
});
|
|
it('late completion clears only the matching displayed lock', async () => {
|
const w = await open({ ...base, phase: 'UNKNOWN', canCancel: false, canResume: false });
|
const complete = mocks.on.mock.calls.find(([name]) => name === 'completed')![1];
|
complete({ printRecordId: 'other', requestId: 'request' });
|
await flushPromises();
|
expect(w.text()).toContain('不能取消或重复打印');
|
complete({ printRecordId: 'copy', requestId: 'request' });
|
await flushPromises();
|
expect(w.text()).toContain('占用已解除');
|
expect(w.text()).not.toContain('刷新状态 / 补交回执');
|
expect(mocks.cancel).not.toHaveBeenCalled();
|
w.unmount();
|
});
|
|
it('closes the status dialog before resuming and restores it on failure', async () => {
|
let reject!: (error: Error) => void;
|
mocks.resume.mockReturnValue(
|
new Promise((_, r) => {
|
reject = r;
|
}),
|
);
|
const w = await open();
|
await click(w, '继续重打');
|
expect(w.findAll('button')).toHaveLength(0);
|
expect(mocks.resume).toHaveBeenCalledTimes(1);
|
reject(new Error('预览加载失败'));
|
await flushPromises();
|
expect(w.text()).toContain('预览加载失败');
|
expect(w.text()).toContain('继续重打');
|
w.unmount();
|
});
|