kt-template-admin/test/components/ktTable/hooks/useKtTableActions.spec.tsx

128 lines
3.5 KiB
TypeScript

/* @vitest-environment happy-dom */
/* eslint-disable vue/one-component-per-file, vue/require-default-prop */
import { mount } from '@vue/test-utils';
import { defineComponent, h } from 'vue';
import { useKtTableActions } from '@test-source/apps/web-antdv-next/src/components/ktTable/hooks/useKtTableActions';
import { describe, expect, it, vi } from 'vitest';
vi.mock('antdv-next', () => ({
Button: defineComponent({
name: 'MockButton',
inheritAttrs: false,
setup(_, { attrs, slots }) {
return () =>
h(
'button',
{
disabled: attrs.disabled,
onClick: attrs.onClick,
},
slots.default?.(),
);
},
}),
Modal: { confirm: vi.fn() },
Tooltip: defineComponent({
name: 'MockTooltip',
props: { title: String },
setup(props, { slots }) {
return () =>
h('span', { 'data-disabled-reason': props.title }, slots.default?.());
},
}),
}));
function createActionRuntime() {
const context = {
formApi: {},
getRows: vi.fn(() => []),
getSearchValues: vi.fn(async () => ({})),
registerHook: vi.fn(),
reload: vi.fn(async () => {}),
reset: vi.fn(async () => {}),
search: vi.fn(async () => {}),
selectedRowKeys: vi.fn(() => []),
selectedRows: vi.fn(() => []),
setSearchValues: vi.fn(async () => {}),
unregisterHook: vi.fn(),
} as any;
return useKtTableActions({
context,
permissions: {
filterVisibleActions: (actions: any[]) => actions,
filterVisibleButtons: (buttons: any[]) => buttons,
resolveBoolean: (value: unknown, fallback: boolean) =>
typeof value === 'boolean' ? value : fallback,
},
props: {
buttons: [],
modules: [],
rowActions: [],
showDefaultButtons: false,
} as any,
reload: context.reload,
reset: context.reset,
runHook: vi.fn(async () => {}),
search: context.search,
});
}
describe('ktTable disabled row action reason', () => {
it('keeps a disabled action visible and exposes its readable reason', async () => {
const onClick = vi.fn();
const runtime = createActionRuntime();
const Harness = defineComponent({
setup() {
return () =>
runtime.renderRowAction(
{
disabled: true,
disabledReason: () => 'TCP 仅支持端口转发 CRUD',
key: 'keeper',
label: '启用 Keeper',
onClick,
},
{ id: 'tcp-1' },
);
},
});
const wrapper = mount(Harness);
expect(wrapper.text()).toContain('启用 Keeper');
expect(wrapper.get('[data-disabled-reason]').attributes()).toMatchObject({
'data-disabled-reason': 'TCP 仅支持端口转发 CRUD',
});
await wrapper.get('button').trigger('click');
expect(onClick).not.toHaveBeenCalled();
});
it('executes an enabled row action without a disabled tooltip', async () => {
const onClick = vi.fn();
const runtime = createActionRuntime();
const Harness = defineComponent({
setup() {
return () =>
runtime.renderRowAction(
{
disabled: false,
disabledReason: 'not rendered',
key: 'edit',
label: '编辑',
onClick,
},
{ id: 'udp-1' },
);
},
});
const wrapper = mount(Harness);
expect(wrapper.find('[data-disabled-reason]').exists()).toBe(false);
await wrapper.get('button').trigger('click');
expect(onClick).toHaveBeenCalledOnce();
});
});