import { readFileSync } from 'node:fs';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
import { createInputTableRowClickHandler, getInputTableCellInteractionAttrs } from '../helpers/rowSelection';
|
|
// Exercise actual SFC handlers without loading unrelated stores and modal components.
|
const source = readFileSync('apps/jnpf-web-apps-main/src/components/Jnpf/InputTable/src/InputTable.vue', 'utf8');
|
const loaderSource = readFileSync('packages/jnpf/utils/src/helpers/common.ts', 'utf8');
|
const loader = new Function(`${loaderSource.match(/export function getScriptFunc\(str\) \{[\s\S]*?\n\}/)![0].replace('export ', '')}; return getScriptFunc;`)();
|
const functions = ['getCellClickHandler', 'onFormClick', 'getCellInteractionAttrs']
|
.map((name) => source.match(new RegExp(`function ${name}\\([^]*?\\n\\}`))![0])
|
.join('\n');
|
|
function harness(
|
options: { disabled?: boolean; rowReadonly?: boolean; controlDisabled?: boolean; detailed?: boolean; displayOnly?: boolean; script?: string } = {},
|
) {
|
const open = vi.fn();
|
const field = {
|
formId: 'directory',
|
on: { click: options.script ?? '({ rowIndex, rowData, onlineUtils }) => onlineUtils.open(rowIndex, rowData)' },
|
config: { __config__: { jnpfKey: 'input', isDisplayOnly: options.displayOnly } },
|
};
|
const rows = Array.from({ length: 25 }, (_, index) => ({ id: `row-${index}`, folder: '' }));
|
const state = { tableFormData: rows.map(() => [field]), dataSource: rows, activeRowIndex: 0 };
|
const getScopedParameter = vi.fn(() => ({ formData: { rows }, onlineUtils: { open } }));
|
const handlers = new Function(
|
'deps',
|
`const { props, state, getRowReadonly, getConfById, getScriptFunc, getScopedParameter, getInputTableCellInteractionAttrs } = deps; ${functions}; return { onFormClick, getCellInteractionAttrs };`,
|
)({
|
props: { disabled: options.disabled },
|
state,
|
getRowReadonly: () => !!options.rowReadonly,
|
getConfById: () => ({ readonly: true, disabled: options.controlDisabled, detailed: options.detailed }),
|
getScriptFunc: loader,
|
getScopedParameter,
|
getInputTableCellInteractionAttrs,
|
});
|
return { ...handlers, state, rows, open, getScopedParameter };
|
}
|
|
describe('configured subtable click', () => {
|
it('wires both native layouts and uses full row indexes in paginated tables', () => {
|
expect(source).toContain('@click="onFormClick(index, cIndex, $event)"');
|
expect(source).toContain('@click="onFormClick(getRealIndex(index), cIndex, $event)"');
|
});
|
it('runs once for a readonly input on page 3 without changing row selection', () => {
|
const h = harness();
|
const updateSelection = vi.fn();
|
const row = document.createElement('div');
|
const cell = document.createElement('div');
|
const input = document.createElement('input');
|
input.readOnly = true;
|
Object.entries(h.getCellInteractionAttrs('directory', 23)).forEach(([key, value]) => cell.setAttribute(key, String(value)));
|
row.append(cell);
|
cell.append(input);
|
const selection = createInputTableRowClickHandler({
|
getRowKey: (r: { id: string }) => r.id,
|
getSelectedRowKeys: () => [],
|
getSelectedRows: () => [],
|
isEnabled: () => true,
|
isRowReadonly: () => false,
|
updateSelection,
|
});
|
input.addEventListener('click', (event) => h.onFormClick(23, 0, event));
|
row.addEventListener('click', selection(h.rows[23]).onClick);
|
input.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
expect(h.open).toHaveBeenCalledExactlyOnceWith(23, h.rows[23]);
|
expect(h.getScopedParameter).toHaveBeenCalledWith(23);
|
expect(h.state.activeRowIndex).toBe(23);
|
expect(updateSelection).not.toHaveBeenCalled();
|
});
|
it.each([
|
{ disabled: true },
|
{ rowReadonly: true },
|
{ controlDisabled: true },
|
{ detailed: true },
|
{ displayOnly: true },
|
{ script: '' },
|
{ script: 'not valid javascript' },
|
{ script: '({ value: 1 })' },
|
])('does not execute or claim a blocked readonly cell: %j', (options) => {
|
const h = harness(options);
|
h.onFormClick(1, 0, new MouseEvent('click'));
|
expect(h.open).not.toHaveBeenCalled();
|
expect(h.getCellInteractionAttrs('directory', 1)).not.toHaveProperty('data-input-table-interactive');
|
});
|
it('passes the native event and current row data to the script', () => {
|
const h = harness({ script: '({ data, rowIndex, rowData, onlineUtils }) => onlineUtils.open(data, rowIndex, rowData)' });
|
const event = new MouseEvent('click');
|
h.onFormClick(1, 0, event);
|
expect(h.open).toHaveBeenCalledExactlyOnceWith(event, 1, h.rows[1]);
|
});
|
it('ignores removed rows', () => {
|
const h = harness();
|
h.onFormClick(25, 0, new MouseEvent('click'));
|
expect(h.open).not.toHaveBeenCalled();
|
});
|
});
|