mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-11-14 19:07:12 +00:00
54 lines
3.8 KiB
TypeScript
54 lines
3.8 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test, { after } from 'node:test';
|
|
import React from 'react';
|
|
import { act, create, type ReactTestRenderer } from 'react-test-renderer';
|
|
import { SftpPaneFileList } from './SftpPaneFileList';
|
|
import { TooltipProvider } from '../ui/tooltip';
|
|
import { installDomEnvironment } from '../test-support/renderReactDom';
|
|
import { createEmptyPane } from '../../application/state/sftp/types';
|
|
|
|
const environment = globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean };
|
|
const previous = environment.IS_REACT_ACT_ENVIRONMENT;
|
|
environment.IS_REACT_ACT_ENVIRONMENT = true;
|
|
after(() => { environment.IS_REACT_ACT_ENVIRONMENT = previous; });
|
|
|
|
test('reconnect listing update keeps scroll, while sorting and filters reveal the selection', async (t) => {
|
|
const dom = installDomEnvironment();
|
|
t.after(() => dom.cleanup());
|
|
let scrolls = 0;
|
|
const container = { querySelectorAll: () => [{ dataset: { entryName: 'selected' }, scrollIntoView: () => { scrolls += 1; } }] };
|
|
const noop = () => {};
|
|
const selected = { name: 'selected', type: 'file' as const, size: 1, sizeFormatted: '1 B', lastModified: 0, lastModifiedFormatted: '' };
|
|
const added = { ...selected, name: 'added' };
|
|
let props: React.ComponentProps<typeof SftpPaneFileList> = {
|
|
t: (key) => key, pane: { ...createEmptyPane('pane'), connection: { id: 'conn', hostId: 'host', hostLabel: 'Host', isLocal: false, status: 'connected', currentPath: '/browsed' }, selectedFiles: new Set(['selected']), files: [selected] },
|
|
side: 'left', isPaneFocused: true,
|
|
sorting: { sortField: 'name', sortOrder: 'asc', directoriesFirst: true,
|
|
columnWidths: { name: 50, modified: 24, size: 7, type: 9, owner: 10 },
|
|
visibleColumns: { name: true, modified: true, size: true, type: true, owner: true },
|
|
handleSort: noop, handleResizeStart: noop, toggleColumnVisibility: noop, toggleDirectoriesFirst: noop },
|
|
fileListRef: { current: container as unknown as HTMLDivElement },
|
|
handleFileListScroll: noop, shouldVirtualize: false, totalHeight: 0, sortedDisplayFiles: [selected],
|
|
isDragOverPane: false, draggedFiles: null, onRefresh: noop, onNavigateTo: noop, onClearSelection: noop,
|
|
setShowNewFolderDialog: noop, setShowNewFileDialog: noop, getNextUntitledName: () => '', setNewFileName: noop, setFileNameError: noop,
|
|
dragOverEntry: null, handleRowSelect: noop, handleRowOpen: noop, handleFileDragStart: noop,
|
|
onDragEnd: noop, handleEntryDragOver: noop, handleRowDragLeave: noop, handleEntryDrop: noop,
|
|
onCopyToOtherPane: noop, onMoveEntriesToPath: async () => {}, openRenameDialog: noop, openDeleteConfirm: noop,
|
|
rowHeight: 28, visibleRows: [],
|
|
};
|
|
const render = () => React.createElement(TooltipProvider, null, React.createElement(SftpPaneFileList, props));
|
|
let renderer: ReactTestRenderer;
|
|
await act(async () => { renderer = create(render(), { createNodeMock: (element) => element.props['data-section'] === 'terminal-sftp-list' ? container : null }); });
|
|
assert.equal(scrolls, 1);
|
|
props = { ...props, pane: { ...props.pane, files: [selected, added] }, sortedDisplayFiles: [added, selected] };
|
|
await act(async () => { renderer.update(render()); });
|
|
assert.equal(scrolls, 1, 'a reconnect listing update must not pull the viewport back to the selection');
|
|
props = { ...props, sorting: { ...props.sorting, sortOrder: 'desc' }, sortedDisplayFiles: [...props.sortedDisplayFiles] };
|
|
await act(async () => { renderer.update(render()); });
|
|
assert.equal(scrolls, 2, 'sorting retains the prior reveal-selection behavior');
|
|
props = { ...props, pane: { ...props.pane, filter: 'selected' }, sortedDisplayFiles: [...props.sortedDisplayFiles] };
|
|
await act(async () => { renderer.update(render()); });
|
|
assert.equal(scrolls, 3, 'filter changes retain the prior reveal-selection behavior');
|
|
await act(async () => { renderer.unmount(); });
|
|
});
|