刘光辉
6 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { flushPromises, mount } from '@vue/test-utils';
 
import { beforeEach, describe, expect, it, vi } from 'vitest';
 
import FileCompareSelectModal from '../FileCompareSelectModal.vue';
 
const mocks = vi.hoisted(() => ({ init: undefined as any, versions: vi.fn(), create: vi.fn(), close: vi.fn() }));
const formMocks = vi.hoisted(() => ({ config: undefined as any, reset: vi.fn(), validate: vi.fn() }));
vi.mock('#/api/x/dms/fileCenter', () => ({ getDocumentVersions: mocks.versions }));
vi.mock('#/api/x/dms/compare', () => ({ createDmsCompareSession: mocks.create }));
vi.mock('@jnpf/utils', () => ({ formatToDateTime: (v: string) => v }));
vi.mock('@jnpf/ui/form', () => ({
  BasicForm: { name: 'BasicForm', template: '<div data-test="compare-form" />' },
  useForm: (config: any) => {
    formMocks.config = config;
    return [vi.fn(), { resetFields: formMocks.reset, validate: formMocks.validate }];
  },
}));
vi.mock('@jnpf/ui/modal', async () => {
  const { defineComponent, h } = await import('vue');
  return {
    BasicModal: defineComponent({
      name: 'BasicModal',
      emits: ['ok', 'cancel'],
      setup:
        (_, { slots }) =>
        () =>
          h('section', slots.default?.()),
    }),
    useModalInner: (init: any) => {
      mocks.init = init;
      return [vi.fn(), { closeModal: mocks.close }];
    },
  };
});
 
const item = { id: 'v3', documentId: 'doc-1', versionNo: 3, name: 'SOP.docx', fileName: 'SOP.docx', resourceType: 'FILE_VERSION', createdAt: '2026-09-01' };
const options = {
  global: {
    stubs: {
      'a-descriptions': true,
      'a-descriptions-item': true,
      'a-alert': true,
      'a-button': true,
      'jnpf-empty': true,
    },
  },
};
 
beforeEach(() => {
  vi.clearAllMocks();
  formMocks.reset.mockResolvedValue(undefined);
  formMocks.validate.mockResolvedValue({ historicalVersionId: 'v1' });
  mocks.versions.mockResolvedValue({ data: { list: [{ ...item, id: 'v1', versionNo: 1 }], hasMore: false } });
});
 
describe('historical version dialog', () => {
  it('submits the fixed current version and selected historical version', async () => {
    const wrapper = mount(FileCompareSelectModal, options);
    await mocks.init({ item });
    await flushPromises();
    const selectProps = formMocks.config.schemas[0].componentProps();
    expect(selectProps.fieldNames).toEqual({ label: 'label', value: 'value' });
    const session = { title: 'v1 → v3' };
    mocks.create.mockResolvedValue(session);
    wrapper.findComponent({ name: 'BasicModal' }).vm.$emit('ok');
    await flushPromises();
    expect(formMocks.validate).toHaveBeenCalledOnce();
    expect(mocks.create).toHaveBeenCalledWith(expect.objectContaining({ documentId: 'doc-1', currentVersionId: 'v3', historicalVersionId: 'v1' }));
    expect(wrapper.emitted('compare')).toEqual([[session]]);
    wrapper.unmount();
  });
 
  it('does not reopen comparison after the user cancels an in-flight request', async () => {
    const wrapper = mount(FileCompareSelectModal, options);
    await mocks.init({ item });
    await flushPromises();
    formMocks.config.schemas[0].componentProps().onChange('v1');
    let resolve!: (data: any) => void;
    mocks.create.mockReturnValue(
      new Promise((r) => {
        resolve = r;
      }),
    );
    const modal = wrapper.findComponent({ name: 'BasicModal' });
    modal.vm.$emit('ok');
    await flushPromises();
    modal.vm.$emit('cancel');
    resolve({ title: 'late result' });
    await flushPromises();
    expect(wrapper.emitted('compare')).toBeUndefined();
    wrapper.unmount();
  });
});