import { shallowMount } from '@vue/test-utils';
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import FieldCatalogPage from '../index.vue';
|
import pageSource from '../index.vue?raw';
|
|
const apiMocks = vi.hoisted(() => ({ getFieldPage: vi.fn() }));
|
const navigationMocks = vi.hoisted(() => ({ route: vi.fn() }));
|
const permissionState = vi.hoisted(() => ({ allowed: true }));
|
const tableState = vi.hoisted(() => ({ config: undefined as any, reload: vi.fn() }));
|
|
vi.mock('#/api/x/eln/fields', () => ({
|
disableField: vi.fn(),
|
enableField: vi.fn(),
|
getFieldPage: apiMocks.getFieldPage,
|
promoteFieldToGlobal: vi.fn(),
|
}));
|
|
vi.mock('#/utils/jnpf', () => ({ getJnpfAppEnCode: () => '', onlineUtils: navigationMocks }));
|
|
vi.mock('@jnpf/hooks', () => ({
|
useMessage: () => ({ createMessage: { success: vi.fn(), warning: vi.fn() } }),
|
usePermission: () => ({ hasBtnP: vi.fn(() => permissionState.allowed) }),
|
}));
|
|
vi.mock('@jnpf/ui/form', () => ({
|
BasicForm: { name: 'BasicForm', template: '<div />' },
|
useForm: () => [vi.fn(), { getFieldsValue: () => ({}), resetFields: vi.fn() }],
|
}));
|
|
vi.mock('@jnpf/ui/modal', () => ({
|
BasicModal: { name: 'BasicModal', template: '<div><slot /></div>' },
|
useModal: () => [vi.fn(), { closeModal: vi.fn(), openModal: vi.fn() }],
|
}));
|
|
vi.mock('@jnpf/ui/drawer', () => ({ useDrawer: () => [vi.fn(), { openDrawer: vi.fn() }] }));
|
|
vi.mock('@jnpf/ui/vxeTable', () => ({
|
BasicVxeTable: { name: 'BasicVxeTable', template: '<div><slot name="tableTitle" /></div>' },
|
TableAction: { name: 'TableAction', template: '<div />' },
|
useVxeTable: (config: any) => {
|
tableState.config = config;
|
return [vi.fn(), { reload: tableState.reload }];
|
},
|
}));
|
|
describe('eLN field catalog page', () => {
|
beforeEach(() => {
|
vi.clearAllMocks();
|
permissionState.allowed = true;
|
tableState.config = undefined;
|
apiMocks.getFieldPage.mockResolvedValue({
|
data: { list: [], pagination: { currentPage: 1, pageSize: 20, total: 0 } },
|
});
|
});
|
|
it('uses the low-code page skeleton without page-level cards', () => {
|
const searchIndex = pageSource.indexOf('jnpf-content-wrapper-search-box');
|
const contentIndex = pageSource.indexOf('jnpf-content-wrapper-content');
|
|
expect(pageSource).toContain('<div class="jnpf-content-wrapper">');
|
expect(pageSource).toContain('<BasicForm');
|
expect(pageSource).toContain('<BasicVxeTable');
|
expect(searchIndex).toBeGreaterThan(0);
|
expect(contentIndex).toBeGreaterThan(searchIndex);
|
expect(pageSource).not.toContain('a-card');
|
});
|
|
it('relies on menu reachability instead of button permissions', () => {
|
expect(pageSource).not.toContain('usePermission');
|
expect(pageSource).not.toContain('hasBtnP');
|
expect(pageSource).not.toContain('auth:');
|
expect(pageSource).not.toContain('status="403"');
|
});
|
|
it('uses the upgrade wording for promoting a field to global scope', () => {
|
expect(pageSource).toContain("label: '升级为全局'");
|
expect(pageSource).toContain('已升级为全局字段');
|
expect(pageSource).toContain("return '升级为全局字段'");
|
expect(pageSource).not.toContain('升格');
|
});
|
|
it('shows the owning template and opens field details', () => {
|
expect(pageSource).toContain("dataIndex: 'mubanBianhao'");
|
expect(pageSource).toContain("title: '归属模板'");
|
expect(pageSource).toContain("label: '详情'");
|
expect(pageSource).toContain("field: 'mubanBianhao'");
|
});
|
|
it('opens LIMS source maintenance as an independent ELN page', async () => {
|
const wrapper = shallowMount(FieldCatalogPage, {
|
global: {
|
stubs: {
|
BasicVxeTable: false,
|
'a-alert': true,
|
'a-button': { template: '<button><slot /></button>' },
|
'a-form-item': true,
|
'a-tag': true,
|
'a-textarea': true,
|
},
|
},
|
});
|
|
await wrapper.get('[data-test="open-lims-sources"]').trigger('click');
|
|
expect(navigationMocks.route).toHaveBeenCalledWith('/eln/sources', { title: 'LIMS 数据项' });
|
});
|
|
it('loads the catalog without a button permission decision', () => {
|
permissionState.allowed = false;
|
shallowMount(FieldCatalogPage, {
|
global: {
|
stubs: {
|
'a-alert': true,
|
'a-button': true,
|
'a-form-item': true,
|
'a-tag': true,
|
'a-textarea': true,
|
Result: true,
|
},
|
},
|
});
|
|
expect(tableState.config.immediate).toBe(true);
|
});
|
|
it('normalizes paging filters and returns the backend page contract', async () => {
|
shallowMount(FieldCatalogPage, {
|
global: {
|
stubs: {
|
'a-alert': true,
|
'a-button': true,
|
'a-form-item': true,
|
'a-tag': true,
|
'a-textarea': true,
|
},
|
},
|
});
|
|
expect(tableState.config.immediate).toBe(true);
|
const query = tableState.config.beforeFetch({
|
bizEnabled: 'enabled',
|
currentPage: 2,
|
keyword: ' 样品编号 ',
|
pageSize: 50,
|
zuoyongFanwei: 'GLOBAL',
|
});
|
expect(query).toEqual({
|
bizEnabled: 'enabled',
|
currentPage: 2,
|
keyword: '样品编号',
|
pageSize: 50,
|
zuoyongFanwei: 'GLOBAL',
|
});
|
|
const result = await tableState.config.api(query);
|
expect(apiMocks.getFieldPage).toHaveBeenCalledWith(query);
|
expect(result).toEqual({ data: { list: [], pagination: { currentPage: 1, pageSize: 20, total: 0 } } });
|
});
|
});
|