/* @vitest-environment happy-dom */
|
|
import { flushPromises, mount } from '@vue/test-utils';
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import SourcePathDrawer from '../SourcePathDrawer.vue';
|
import drawerSource from '../SourcePathDrawer.vue?raw';
|
|
const apiMocks = vi.hoisted(() => ({
|
createSourcePath: vi.fn(),
|
getSourceObjectFields: vi.fn(),
|
getSourceObjects: vi.fn(),
|
getSourcePreviewSamples: vi.fn(),
|
suggestFieldCode: vi.fn(),
|
}));
|
const drawerMocks = vi.hoisted(() => ({
|
changeLoading: vi.fn(),
|
changeOkLoading: vi.fn(),
|
closeDrawer: vi.fn(),
|
init: undefined as (() => Promise<void>) | undefined,
|
}));
|
|
vi.mock('#/api/x/eln/fields', () => ({ suggestFieldCode: apiMocks.suggestFieldCode }));
|
vi.mock('#/api/x/eln/sources', () => apiMocks);
|
vi.mock('@jnpf/ui/drawer', () => ({
|
BasicDrawer: {
|
emits: ['ok'],
|
name: 'BasicDrawer',
|
template: '<aside><slot /><button data-test="drawer-ok" @click="$emit(\'ok\')">确认</button></aside>',
|
},
|
useDrawerInner: (init: () => Promise<void>) => {
|
drawerMocks.init = init;
|
return [vi.fn(), drawerMocks];
|
},
|
}));
|
|
function mountDrawer() {
|
return mount(SourcePathDrawer, {
|
global: {
|
stubs: {
|
'a-alert': { props: ['message'], template: '<div>{{ message }}<slot /></div>' },
|
'a-input': {
|
emits: ['update:value'],
|
props: ['value'],
|
template: '<input :value="value" @input="$emit(\'update:value\', $event.target.value)" />',
|
},
|
'a-select': {
|
emits: ['change'],
|
props: ['options', 'value'],
|
template:
|
'<select :value="value" @change="$emit(\'change\', $event.target.value)"><option value=""></option><option v-for="item in options" :key="item.value" :value="item.value">{{ item.label }}</option></select>',
|
},
|
},
|
},
|
});
|
}
|
|
describe('来源路径新增抽屉', () => {
|
beforeEach(() => {
|
vi.clearAllMocks();
|
drawerMocks.init = undefined;
|
apiMocks.getSourceObjects.mockResolvedValue({ data: [{ displayName: '检验项', id: 'task', rootAnchor: true }] });
|
apiMocks.getSourceObjectFields.mockResolvedValue({ data: [{ dataType: 'DATE', displayName: '生产日期', id: 'production-date' }] });
|
apiMocks.getSourcePreviewSamples.mockResolvedValue({ data: [{ id: 'sample-1', sampleName: '样品 A', testNo: 'JY001' }] });
|
apiMocks.suggestFieldCode.mockResolvedValueOnce({ data: { code: 'request_date' } }).mockResolvedValueOnce({ data: { code: 'production_date' } });
|
apiMocks.createSourcePath.mockResolvedValue({ data: { id: 'path-1' } });
|
});
|
|
it('打开时才加载元数据和校验样例', async () => {
|
mountDrawer();
|
expect(apiMocks.getSourceObjects).not.toHaveBeenCalled();
|
expect(apiMocks.getSourcePreviewSamples).not.toHaveBeenCalled();
|
|
await drawerMocks.init?.();
|
await flushPromises();
|
|
expect(apiMocks.getSourceObjects).toHaveBeenCalledTimes(1);
|
expect(apiMocks.getSourceObjectFields).toHaveBeenCalledWith('task');
|
expect(apiMocks.getSourcePreviewSamples).toHaveBeenCalledTimes(1);
|
});
|
|
it('校验样例加载失败时仍加载路径字段', async () => {
|
apiMocks.getSourcePreviewSamples.mockRejectedValue(new Error('preview unavailable'));
|
const wrapper = mountDrawer();
|
|
await drawerMocks.init?.();
|
await flushPromises();
|
|
expect(apiMocks.getSourceObjectFields).toHaveBeenCalledWith('task');
|
expect(wrapper.text()).toContain('预览检验项暂不可用,请稍后重试');
|
});
|
|
it('校验并发布后通知页面刷新', async () => {
|
const wrapper = mountDrawer();
|
await drawerMocks.init?.();
|
await flushPromises();
|
|
await wrapper.get('[data-test="path-display-name"]').setValue('请验单生产日期');
|
await wrapper.get('[data-test="path-output-field"]').setValue('production-date');
|
await wrapper.get('[data-test="path-sample"]').setValue('sample-1');
|
await wrapper.get('[data-test="drawer-ok"]').trigger('click');
|
await flushPromises();
|
|
expect(apiMocks.createSourcePath).toHaveBeenCalledWith(
|
expect.objectContaining({
|
displayName: '请验单生产日期',
|
outputFieldId: 'production-date',
|
rootObjectId: 'task',
|
sampleId: 'sample-1',
|
targetObjectId: 'task',
|
}),
|
);
|
expect(wrapper.emitted('success')).toHaveLength(1);
|
expect(drawerMocks.closeDrawer).toHaveBeenCalledTimes(1);
|
});
|
|
it('显示完整占位提示并使用标准抽屉底部', () => {
|
expect(drawerSource).toContain('placeholder="请输入路径名称,例如:请验单生产日期"');
|
expect(drawerSource).toContain('placeholder="请选择到达对象"');
|
expect(drawerSource).toContain('placeholder="请选择可返回的业务内容"');
|
expect(drawerSource).toContain('placeholder="请选择用于校验发布的检验项"');
|
expect(drawerSource).toContain('@ok="createPath"');
|
expect(drawerSource).toContain('show-footer');
|
});
|
});
|