/* @vitest-environment happy-dom */
|
/* eslint-disable vue/one-component-per-file */
|
|
import type { VueWrapper } from '@vue/test-utils';
|
|
import { mount } from '@vue/test-utils';
|
import { defineComponent, h, nextTick, onMounted } from 'vue';
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import GlobalDmsFolderSelector from '../index.vue';
|
|
const mocks = vi.hoisted(() => ({
|
closeModal: vi.fn(),
|
error: vi.fn(),
|
getDmsFolderTree: vi.fn(),
|
openModal: vi.fn(),
|
register: vi.fn(),
|
}));
|
|
vi.mock('#/router', () => ({ router: { push: vi.fn() } }));
|
vi.mock('#/api/request', () => ({ defHttp: { get: vi.fn() } }));
|
vi.mock('#/api/x/dms/fileCenter', () => ({ getDmsFolderTree: mocks.getDmsFolderTree }));
|
vi.mock('@jnpf/hooks', () => ({ useMessage: () => ({ createMessage: { error: mocks.error } }) }));
|
|
vi.mock('@jnpf/ui/modal', () => ({
|
BasicModal: defineComponent({
|
props: { okButtonProps: { default: () => ({}), type: Object } },
|
emits: ['ok', 'register'],
|
setup(props, { emit, slots }) {
|
onMounted(() => emit('register'));
|
return () =>
|
h('section', [slots.default?.(), h('button', { 'data-test': 'confirm', disabled: props.okButtonProps?.disabled, onClick: () => emit('ok') }, '确定')]);
|
},
|
}),
|
useModal: () => [mocks.register, { closeModal: mocks.closeModal, openModal: mocks.openModal }],
|
}));
|
|
vi.mock('ant-design-vue', () => ({
|
Tree: defineComponent({
|
props: { treeData: { required: true, type: Array } },
|
emits: ['select'],
|
setup(props, { emit }) {
|
return () =>
|
h(
|
'div',
|
(props.treeData as any[]).map((node) => h('button', { 'data-test': `folder-${node.key}`, onClick: () => emit('select', [node.key]) }, node.title)),
|
);
|
},
|
}),
|
}));
|
|
const { onlineUtils } = await import('#/utils/jnpf');
|
|
let wrapper: VueWrapper<any>;
|
|
async function flush(times = 3) {
|
for (let index = 0; index < times; index++) await nextTick();
|
}
|
|
describe('globalDmsFolderSelector', () => {
|
beforeEach(() => {
|
mocks.closeModal.mockReset();
|
mocks.error.mockReset();
|
mocks.getDmsFolderTree.mockReset();
|
mocks.openModal.mockReset();
|
mocks.getDmsFolderTree.mockResolvedValue({
|
data: {
|
hasMore: false,
|
list: [{ hasChildren: false, id: 'folder_001', name: '质量管理部' }],
|
},
|
});
|
wrapper = mount(GlobalDmsFolderSelector, { global: { directives: { loading: {} } } });
|
});
|
|
afterEach(() => {
|
wrapper.unmount();
|
});
|
|
it('selects a folder and invokes onConfirm when the modal confirm action is clicked', async () => {
|
const onConfirm = vi.fn();
|
|
onlineUtils.openDmsFolderSelector(undefined, onConfirm);
|
await flush();
|
await wrapper.get('[data-test="folder-folder_001"]').trigger('click');
|
await wrapper.get('[data-test="confirm"]').trigger('click');
|
|
expect(onConfirm).toHaveBeenCalledWith('folder_001', '质量管理部');
|
expect(mocks.closeModal).toHaveBeenCalledTimes(1);
|
});
|
|
it('renders the modal and root directories while locating a nested initial folder', async () => {
|
mocks.getDmsFolderTree
|
.mockResolvedValueOnce({
|
data: {
|
hasMore: false,
|
list: [{ hasChildren: true, id: 'folder_001', name: '根目录' }],
|
},
|
})
|
.mockImplementationOnce(() => new Promise(() => {}));
|
|
onlineUtils.openDmsFolderSelector('folder_999');
|
await flush();
|
|
expect(mocks.openModal).toHaveBeenCalledWith(true);
|
expect(wrapper.get('[data-test="folder-folder_001"]').text()).toBe('根目录');
|
});
|
|
it('returns a nested folder path without spaces around separators', async () => {
|
const onConfirm = vi.fn();
|
mocks.getDmsFolderTree
|
.mockResolvedValueOnce({
|
data: {
|
hasMore: false,
|
list: [{ hasChildren: true, id: 'folder_001', name: '根目录' }],
|
},
|
})
|
.mockResolvedValueOnce({
|
data: {
|
hasMore: false,
|
list: [{ hasChildren: true, id: 'folder_002', name: 'A' }],
|
},
|
})
|
.mockResolvedValueOnce({
|
data: {
|
hasMore: false,
|
list: [{ hasChildren: false, id: 'folder_003', name: 'B' }],
|
},
|
});
|
|
onlineUtils.openDmsFolderSelector('folder_003', onConfirm);
|
await vi.waitFor(() => expect(wrapper.get('[data-test="confirm"]').attributes('disabled')).toBeUndefined());
|
await wrapper.get('[data-test="confirm"]').trigger('click');
|
|
expect(onConfirm).toHaveBeenCalledWith('folder_003', '根目录/A/B');
|
});
|
|
it('closes the current selector before a confirmation callback opens another selector', async () => {
|
const onConfirm = vi.fn(() => onlineUtils.openDmsFolderSelector());
|
|
onlineUtils.openDmsFolderSelector({ onConfirm });
|
await flush();
|
await wrapper.get('[data-test="folder-folder_001"]').trigger('click');
|
await wrapper.get('[data-test="confirm"]').trigger('click');
|
await vi.waitFor(() => expect(mocks.openModal).toHaveBeenCalledTimes(2));
|
|
expect(onConfirm).toHaveBeenCalledOnce();
|
expect(mocks.openModal).toHaveBeenCalledTimes(2);
|
expect(mocks.closeModal).toHaveBeenCalledTimes(1);
|
expect(mocks.closeModal.mock.invocationCallOrder[0]).toBeLessThan(mocks.openModal.mock.invocationCallOrder[1]!);
|
});
|
});
|