/* @vitest-environment happy-dom */
|
/* eslint-disable vue/one-component-per-file */
|
|
import type { DmsFileCenterItem } from '#/api/x/dms/fileCenter';
|
|
import { flushPromises, mount } from '@vue/test-utils';
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import FileOperationLogModal from '../FileOperationLogModal.vue';
|
|
const apiMocks = vi.hoisted(() => ({ getFileOperationLogs: vi.fn() }));
|
const messageMocks = vi.hoisted(() => ({ error: vi.fn() }));
|
const modalState = vi.hoisted(() => ({ init: undefined as ((data: { item: DmsFileCenterItem }) => void) | undefined }));
|
const tableState = vi.hoisted(() => ({ config: undefined as any, pagination: { current: 1, pageSize: 10 } }));
|
|
vi.mock('#/api/x/dms/fileCenter', () => ({ getFileOperationLogs: apiMocks.getFileOperationLogs }));
|
vi.mock('@jnpf/hooks', () => ({ useMessage: () => ({ createMessage: messageMocks }) }));
|
vi.mock('@jnpf/utils', () => ({ formatToDateTime: (value: string) => value }));
|
|
vi.mock('@jnpf/ui/modal', async () => {
|
const { defineComponent, h } = await import('vue');
|
|
return {
|
BasicModal: defineComponent({
|
name: 'BasicModal',
|
setup:
|
(_, { slots }) =>
|
() =>
|
h('section', slots.default?.()),
|
}),
|
useModalInner: (init: (data: { item: DmsFileCenterItem }) => void) => {
|
modalState.init = init;
|
return [vi.fn(), {}];
|
},
|
};
|
});
|
|
vi.mock('@jnpf/ui/vxeTable', async () => {
|
const { defineComponent, h } = await import('vue');
|
|
return {
|
BasicVxeTable: defineComponent({
|
name: 'BasicVxeTable',
|
props: {
|
dataSource: { default: () => [], type: Array },
|
loading: Boolean,
|
pagination: { default: undefined, type: [Boolean, Object] },
|
},
|
emits: ['change'],
|
setup(props, { emit }) {
|
return () =>
|
h(
|
'button',
|
{
|
'data-current-page': (props.pagination as any)?.current,
|
'data-page-size': (props.pagination as any)?.pageSize,
|
'data-record-count': props.dataSource.length,
|
'data-test': 'operation-log-table',
|
onClick: () => {
|
tableState.pagination = { current: 2, pageSize: 20 };
|
emit('change', { action: 'paginate' });
|
},
|
type: 'button',
|
},
|
'操作记录',
|
);
|
},
|
}),
|
useVxeTable: (config: any) => {
|
tableState.config = config;
|
return [vi.fn(), { getPaginationRef: () => tableState.pagination }];
|
},
|
};
|
});
|
|
const fileItem: DmsFileCenterItem = {
|
createdAt: '2026-09-01T00:00:00Z',
|
documentId: 'document-1',
|
fileName: '质量手册.docx',
|
id: 'version-1',
|
name: '质量手册.docx',
|
resourceType: 'FILE_VERSION',
|
versionNo: 1,
|
};
|
|
describe('file operation log modal', () => {
|
beforeEach(() => {
|
vi.clearAllMocks();
|
tableState.pagination = { current: 1, pageSize: 10 };
|
apiMocks.getFileOperationLogs.mockResolvedValue({
|
data: {
|
currentPage: 1,
|
list: [{ id: 'log-1', occurredAt: '2026-09-20T08:00:00Z', operationContent: '查看文件' }],
|
pageSize: 10,
|
total: 21,
|
},
|
});
|
});
|
|
it('uses the standard table as a controlled paginated view', async () => {
|
const wrapper = mount(FileOperationLogModal, {
|
global: {
|
stubs: {
|
'a-alert': true,
|
'a-button': true,
|
'a-tooltip': true,
|
'jnpf-input': true,
|
},
|
},
|
});
|
|
modalState.init?.({ item: fileItem });
|
await flushPromises();
|
|
expect(tableState.config).toMatchObject({ rowKey: 'id', showIndexColumn: false, showTableSetting: false });
|
expect(apiMocks.getFileOperationLogs).toHaveBeenLastCalledWith(fileItem.id, {
|
currentPage: 1,
|
keyword: undefined,
|
pageSize: 10,
|
});
|
|
const table = wrapper.get('[data-test="operation-log-table"]');
|
expect(table.attributes('data-record-count')).toBe('1');
|
expect(table.attributes('data-current-page')).toBe('1');
|
expect(table.attributes('data-page-size')).toBe('10');
|
|
apiMocks.getFileOperationLogs.mockResolvedValueOnce({
|
data: { currentPage: 2, list: [], pageSize: 20, total: 21 },
|
});
|
await table.trigger('click');
|
await flushPromises();
|
|
expect(apiMocks.getFileOperationLogs).toHaveBeenLastCalledWith(fileItem.id, {
|
currentPage: 2,
|
keyword: undefined,
|
pageSize: 20,
|
});
|
|
wrapper.unmount();
|
});
|
});
|