Skip to content

Commit

Permalink
FileBrowserDialog: add basic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
maksis committed Jan 1, 2025
1 parent 14f0d31 commit ba005f6
Show file tree
Hide file tree
Showing 30 changed files with 517 additions and 246 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"@types/webpack": "^5.28.0",
"@typescript-eslint/eslint-plugin": "^8.2.0",
"@typescript-eslint/parser": "^8.2.0",
"airdcpp-apisocket": "^3.0.0-beta.6",
"airdcpp-apisocket": "^3.0.0-beta.7",
"apexcharts": "^4.3.0",
"babel-jest": "^29.2.2",
"babel-loader": "^9.0.1",
Expand Down
9 changes: 1 addition & 8 deletions src/components/action-menu/MenuFormDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useRef } from 'react';
import * as React from 'react';
import { useLocation } from 'react-router';

import Modal, { ModalProps } from 'components/semantic/Modal';
import Form, { FormSaveHandler } from 'components/form/Form';
Expand All @@ -26,7 +25,6 @@ export const MenuFormDialog: React.FC<MenuFormDialogProps> = ({
...other
}) => {
const formRef = useRef<Form | null>(null);
const location = useLocation();
const { t } = useTranslation();
return (
<Modal
Expand All @@ -38,12 +36,7 @@ export const MenuFormDialog: React.FC<MenuFormDialogProps> = ({
icon={icon}
dynamicHeight={true}
>
<Form
ref={formRef}
onSave={onSave}
fieldDefinitions={fieldDefinitions}
location={location}
/>
<Form ref={formRef} onSave={onSave} fieldDefinitions={fieldDefinitions} />
</Modal>
);
};
12 changes: 6 additions & 6 deletions src/components/download/__tests__/DownloadDialog.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ import { waitForElementToBeRemoved, waitFor, fireEvent } from '@testing-library/

import { HistoryStringPathResponse } from 'tests/mocks/api/history';
import {
createTestModalController,
TestModalNavigateButton,
waitForData,
} from 'tests/test-component-helpers';
createTestRouteModalController,
TestRouteModalNavigateButton,
} from 'tests/test-dialog-helpers';
import { waitForData } from 'tests/test-helpers';

// tslint:disable:no-empty
describe('DownloadDialog', () => {
Expand Down Expand Up @@ -86,7 +86,7 @@ describe('DownloadDialog', () => {
const DownloadDialogTest = () => {
return (
<>
<TestModalNavigateButton
<TestRouteModalNavigateButton
modalRoute={`/home/download/${MOCK_FILELIST_ITEM_ID}`}
/>
<DownloadDialog
Expand All @@ -113,7 +113,7 @@ describe('DownloadDialog', () => {
routerProps: { initialEntries: ['/home'] },
});

const modalController = createTestModalController(renderData);
const modalController = createTestRouteModalController(renderData);
return { socket, handleDownload, modalController, ...renderData };
};

Expand Down
22 changes: 11 additions & 11 deletions src/components/filebrowser/FileBrowserLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,19 +141,19 @@ const FileBrowserLayout: React.FC<Props> = ({
}
};

const createDirectory: SubmitCallback = (directoryName) => {
const createDirectory: SubmitCallback = async (directoryName) => {
console.assert(directoryName.length > 0, 'Directory name must be set');
const newPath = currentDirectory + directoryName + pathSeparator;
socket
.post(FilesystemConstants.DIRECTORY_URL, { path: newPath })
.then(() => {
handleDirectoryChanged(newPath);
})
.catch((error: Error) => {
NotificationActions.error({
title: translate('Failed to create directory', t, UI.Modules.COMMON),
message: error.message,
});

try {
await socket.post(FilesystemConstants.DIRECTORY_URL, { path: newPath });
handleDirectoryChanged(newPath);
} catch (error) {
NotificationActions.error({
title: translate('Failed to create directory', t, UI.Modules.COMMON),
message: error.message,
});
}
};

const hasEditAccess = hasAccess(API.AccessEnum.FILESYSTEM_EDIT);
Expand Down
205 changes: 205 additions & 0 deletions src/components/filebrowser/__tests__/FileBrowserDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import {
getConnectedSocket,
getMockServer,
} from 'airdcpp-apisocket/tests/mock-server.js';

import { jest } from '@jest/globals';
import { renderNode } from 'tests/test-containers';

import * as API from 'types/api';

import { fireEvent, waitFor } from '@testing-library/dom';
import FilesystemConstants from 'constants/FilesystemConstants';
import { FilesystemListContentResponse } from 'tests/mocks/api/filesystem';
import { MenuFormDialog } from 'components/action-menu/MenuFormDialog';
import { createTestModalController, useModalButton } from 'tests/test-dialog-helpers';
import { clickButton, waitForData } from 'tests/test-helpers';
import { setInputFieldValues, setupUserEvent } from 'tests/test-form-helpers';

// tslint:disable:no-empty
describe('FileBrowserDialog', () => {
let server: ReturnType<typeof getMockServer>;
const getSocket = async () => {
const { socket } = await getConnectedSocket(server);

// Browse dialog
server.addRequestHandler(
'POST',
FilesystemConstants.LIST_URL,
FilesystemListContentResponse,
);

server.addRequestHandler('POST', FilesystemConstants.DIRECTORY_URL, undefined);

return { socket, server };
};

const renderDialog = async (fieldType: API.SettingTypeEnum, defaultValue = '') => {
const { socket, server, ...other } = await getSocket();

const onSave = jest.fn(() => Promise.resolve());
const caption = 'Test dialog';

const ShareDirectoryDialogTest = () => {
const FormDefinitions: API.SettingDefinition[] = [
{
key: fieldType,
type: fieldType,
default_value: defaultValue,
title: fieldType,
},
];

const { open, onClose, button } = useModalButton();
return (
<>
{button}
{open && (
<MenuFormDialog
title={caption}
onSave={onSave}
icon="test"
fieldDefinitions={FormDefinitions}
onClose={onClose}
/>
)}
</>
);
};

const renderData = renderNode(<ShareDirectoryDialogTest />, socket);

const modalController = createTestModalController(renderData);
return { modalController, onSave, caption, ...renderData, ...other };
};

beforeEach(() => {
server = getMockServer();
});

afterEach(() => {
server.stop();
});

describe('directory selection', () => {
test('should select initial', async () => {
const { getByText, modalController, queryByText, getByRole, onSave, caption } =
await renderDialog(API.SettingTypeEnum.DIRECTORY_PATH);

await modalController.openDialog();

// Check content
await waitFor(() => expect(getByText(caption)).toBeTruthy());

// Open dialog
expect(fireEvent.click(getByText('Browse'))).toBeTruthy();
await waitForData('Loading items', queryByText);

clickButton('Select', getByRole);

// Save
await modalController.closeDialogButton('Continue');

expect(onSave).toHaveBeenCalledTimes(1);
expect(onSave.mock.calls[0]).toMatchSnapshot();
}, 100000);

test('should select child', async () => {
const { getByText, modalController, queryByText, getByRole, onSave, caption } =
await renderDialog(API.SettingTypeEnum.DIRECTORY_PATH);

await modalController.openDialog();

// Check content
await waitFor(() => expect(getByText(caption)).toBeTruthy());

// Open dialog
expect(fireEvent.click(getByText('Browse'))).toBeTruthy();
await waitForData('Loading items', queryByText);

expect(fireEvent.click(getByText('2 folders'))).toBeTruthy();

clickButton('Select', getByRole);

// Save
await modalController.closeDialogButton('Continue');

expect(onSave).toHaveBeenCalledTimes(1);
expect(onSave.mock.calls[0]).toMatchSnapshot();
}, 100000);

test('should create new directory', async () => {
const userEvent = setupUserEvent();
const {
getByText,
modalController,
queryByText,
getByRole,
getByLabelText,
onSave,
caption,
container,
} = await renderDialog(API.SettingTypeEnum.DIRECTORY_PATH);

await modalController.openDialog();

// Check content
await waitFor(() => expect(getByText(caption)).toBeTruthy());

// Open dialog
expect(fireEvent.click(getByText('Browse'))).toBeTruthy();
await waitForData('Loading items', queryByText);

// Create new directory
expect(fireEvent.click(getByText('Create directory'))).toBeTruthy();
await waitFor(() =>
expect(container.querySelector('.ui.action.input.visible')).toBeTruthy(),
);

await setInputFieldValues(
{ userEvent, getByLabelText },
{ 'Create directory': 'New directory' },
);

expect(fireEvent.click(getByText('Create'))).toBeTruthy();
await waitFor(() =>
expect(container.querySelector('.ui.action.input.visible')).toBeFalsy(),
);

// Select the new directory
clickButton('Select', getByRole);

// Save
await modalController.closeDialogButton('Continue');

expect(onSave).toHaveBeenCalledTimes(1);
expect(onSave.mock.calls[0]).toMatchSnapshot();
}, 100000);
});

describe('file selection', () => {
test.skip('should select existing', async () => {
const { getByText, modalController, queryByText, onSave, caption } =
await renderDialog(API.SettingTypeEnum.EXISTING_FILE_PATH);

await modalController.openDialog();

// Check content
await waitFor(() => expect(getByText(caption)).toBeTruthy());

// Open dialog
expect(fireEvent.click(getByText('Browse'))).toBeTruthy();
await waitForData('Loading items', queryByText);

// Go to child directory
expect(fireEvent.click(getByText('2 folders'))).toBeTruthy();
await waitForData('Loading items', queryByText);

// Save
await modalController.closeDialogButton('empty.txt');

expect(onSave).toHaveBeenCalledTimes(1);
expect(onSave.mock.calls[0]).toMatchSnapshot();
}, 100000);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FileBrowserDialog directory selection should create new directory 1`] = `
[
{
"directory_path": "/New directory/",
},
{
"directory_path": "/New directory/",
},
]
`;

exports[`FileBrowserDialog directory selection should select child 1`] = `
[
{
"directory_path": "/2 folders/",
},
{
"directory_path": "/2 folders/",
},
]
`;

exports[`FileBrowserDialog directory selection should select initial 1`] = `
[
{
"directory_path": "/",
},
{
"directory_path": "/",
},
]
`;
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ export const CreateDirectorySection: React.FC<CreateDirectorySectionProps> = ({
t,
}) => (
<Accordion>
<div className="title create-section">
<label htmlFor="create_directory" className="title create-section">
<Icon icon={IconConstants.DROPDOWN} />
{translate('Create directory', t, UI.Modules.COMMON)}
</div>
</label>

<div className="content create-section">
<ActionInput
caption={translate('Create', t, UI.Modules.COMMON)}
icon={IconConstants.CREATE}
handleAction={handleAction}
placeholder={translate('Directory name', t, UI.Modules.COMMON)}
id="create_directory"
/>
</div>
</Accordion>
Expand Down
Loading

0 comments on commit ba005f6

Please sign in to comment.