Skip to content

Commit

Permalink
Add tests for FavoriteHubDialog
Browse files Browse the repository at this point in the history
  • Loading branch information
maksis committed Dec 23, 2024
1 parent d735548 commit 304b194
Show file tree
Hide file tree
Showing 9 changed files with 652 additions and 238 deletions.
440 changes: 213 additions & 227 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
"prepublishOnly": "tx pull -a && npm run build",
"prettier": "prettier --write src"
},
"overrides": {
"tr46": "^5.0.0"
},
"pre-commit": [
"test"
],
Expand All @@ -46,6 +49,7 @@
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.8",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.1.0",
"@testing-library/user-event": "^14.5.2",
"@types/express": "^5.0.0",
"@types/fixed-data-table-2": "^1.0.0",
"@types/he": "^1.1.2",
Expand Down Expand Up @@ -124,6 +128,7 @@
"react-refresh": "^0.14.0",
"react-router": "^7.0.2",
"react-select": "^5.5.6",
"react-select-event": "^5.5.1",
"react-timeseries-charts": "^0.16.1",
"react-toastify": "^11.0.0",
"react-transition-group": "^4.4.5",
Expand Down
168 changes: 168 additions & 0 deletions src/routes/FavoriteHubs/__tests__/FavoriteHubDialog.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import {
getConnectedSocket,
getMockServer,
waitForExpect,
} from 'airdcpp-apisocket/tests/helpers.js';

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

import * as UI from 'types/ui';

import {
createTestModalController,
TestModalNavigateButton,
} from 'tests/test-component-helpers';
import FavoriteHubDialog from '../components/FavoriteHubDialog';
import { getModuleT } from 'utils/TranslationUtils';
import { useTranslation } from 'react-i18next';
import ShareProfileConstants from 'constants/ShareProfileConstants';
import { ShareProfilesListResponse } from 'tests/mocks/api/share-profiles';
import FavoriteHubConstants from 'constants/FavoriteHubConstants';
import {
MOCK_FAVORITE_HUB_ID,
FavoriteHubGetResponse,
} from 'tests/mocks/api/favorite-hubs';
import { setInputFieldValues, setupUserEvent } from 'tests/test-form-helpers';

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

// Data fetch
server.addDataHandler(
'GET',
ShareProfileConstants.PROFILES_URL,
ShareProfilesListResponse,
);
server.addDataHandler(
'GET',
`${FavoriteHubConstants.HUBS_URL}/${MOCK_FAVORITE_HUB_ID}`,
FavoriteHubGetResponse,
);

// Listeners
server.addDataHandler(
'POST',
`${ShareProfileConstants.PROFILES_URL}/listeners/share_profile_added`,
undefined,
);
server.addDataHandler(
'POST',
`${ShareProfileConstants.PROFILES_URL}/listeners/share_profile_updated`,
undefined,
);
server.addDataHandler(
'POST',
`${ShareProfileConstants.PROFILES_URL}/listeners/share_profile_removed`,
undefined,
);

const onCreated = jest.fn();
const onUpdated = jest.fn();

// Save handlers
server.addDataHandler(
'PATCH',
`${FavoriteHubConstants.HUBS_URL}/${MOCK_FAVORITE_HUB_ID}`,
undefined,
onUpdated,
);
server.addDataHandler('POST', FavoriteHubConstants.HUBS_URL, undefined, onCreated);

return { socket, server, onCreated, onUpdated };
};

const renderDialog = async (id: number | null) => {
const { socket, server, ...other } = await getSocket();

const FavoriteHubDialogTest = () => {
const { t } = useTranslation();
const favT = getModuleT(t, UI.Modules.FAVORITE_HUBS);
return (
<>
<TestModalNavigateButton
modalRoute={id ? `/home/entries/${id}` : '/home/entries'}
/>
<FavoriteHubDialog favT={favT} />
</>
);
};

const routes = [
{
path: '/home/*',
Component: FavoriteHubDialogTest,
},
];

const renderData = await renderRoutes(routes, {
socket,
routerProps: { initialEntries: ['/home'] },
});

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

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

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

test('should update existing', async () => {
const userEvent = setupUserEvent();
const { getByText, getByLabelText, modalController, onUpdated } =
await renderDialog(MOCK_FAVORITE_HUB_ID);

await modalController.openDialog();

// Check content
await waitForExpect(() => expect(getByText('Edit favorite hub')).toBeTruthy());

// Edit
await setInputFieldValues(
{ userEvent, getByLabelText },
{
Name: 'Updated name',
},
);

await modalController.closeDialogButton('Save');

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

test('should create new', async () => {
const userEvent = setupUserEvent();
const { getByText, getByLabelText, modalController, onCreated, onUpdated } =
await renderDialog(null);

await modalController.openDialog();

// Check content
await waitForExpect(() => expect(getByText('Add favorite hub')).toBeTruthy());

// Edit
await setInputFieldValues(
{ userEvent, getByLabelText },
{
Name: 'Hub name',
'Hub URL': 'adcs://example.com:1511',
},
);

await modalController.closeDialogButton('Save');

expect(onCreated).toHaveBeenCalledTimes(1);
expect(onCreated.mock.calls[0]).toMatchSnapshot();

// stop();
}, 100000);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FavoriteHubDialog should create new 1`] = `
[
{
"callback_id": 6,
"data": {
"auto_connect": false,
"away_message": null,
"connection_ip_v4": null,
"connection_ip_v6": null,
"connection_mode_v4": null,
"connection_mode_v6": null,
"hub_description": null,
"hub_url": "adcs://example.com:1511",
"name": "Hub name",
"nick": null,
"share_profile": null,
"show_joins": null,
"use_main_chat_notify": null,
"user_description": null,
},
"method": "POST",
"path": "favorite_hubs",
},
]
`;

exports[`FavoriteHubDialog should update existing 1`] = `
[
{
"callback_id": 7,
"data": {
"name": "Updated name",
},
"method": "PATCH",
"path": "favorite_hubs/703302715",
},
]
`;
31 changes: 31 additions & 0 deletions src/tests/mocks/api/favorite-hubs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export const MOCK_FAVORITE_HUB_ID = 703302715;

export const FavoriteHubGetResponse = {
auto_connect: false,
away_message: '',
connect_state: {
current_hub_id: 0,
id: 0,
str: 'Disconnected',
},
connection_ip_v4: '',
connection_ip_v6: '',
connection_mode_v4: null,
connection_mode_v6: null,
fav_show_joins: null,
has_password: false,
hub_description: 'ADC Test hub',
hub_url: 'adc://[::1]:2782',
id: MOCK_FAVORITE_HUB_ID,
log_main: null,
name: 'ADCH++ Debug',
nick: '',
nmdc_encoding: 'utf-8',
share_profile: {
id: null,
str: '',
},
show_joins: null,
use_main_chat_notify: null,
user_description: '',
};
34 changes: 34 additions & 0 deletions src/tests/mocks/api/share-profiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const ShareProfilesListResponse = [
{
default: true,
files: 2004,
id: 28550432,
name: 'Default profile',
size: 60682878029,
str: 'Default profile (Default)',
},
{
default: false,
files: 1848,
id: 0,
name: 'Profile 2',
size: 51592666838,
str: 'Profile 2',
},
{
default: false,
files: 0,
id: 265571564,
name: 'Empty',
size: 0,
str: 'Empty',
},
{
default: false,
files: 0,
id: 1,
name: 'Share hidden',
size: 0,
str: 'Share hidden',
},
];
30 changes: 19 additions & 11 deletions src/tests/test-component-helpers.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import {
act,
fireEvent,
Matcher,
RenderResult,
waitFor,
waitForElementToBeRemoved,
} from '@testing-library/react';
import { waitForExpect } from 'airdcpp-apisocket/tests/helpers.js';
import Button from 'components/semantic/Button';
import { useNavigate } from 'react-router';
import { RouteRenderResult } from './test-containers';

export const waitForUrl = async (pathName: string) => {
await waitForExpect(() => expect(window.location.pathname).toEqual(pathName));
export const waitForUrl = async (
pathName: string,
router: RouteRenderResult['router'],
) => {
await waitForExpect(() => expect(router.state.location.pathname).toEqual(pathName));
};

export const waitForData = async (
text: string,
text: Matcher,
queryByText: RenderResult['queryByText'],
) => {
await waitFor(() => queryByText(text));
Expand All @@ -37,34 +42,37 @@ export const TestModalNavigateButton = ({ modalRoute }: { modalRoute: string })
);
};

export const DataLoaderText = /Loading data.*/;

export const createTestModalController = ({
getByRole,
getByText,
queryByText,
}: RenderResult) => {
const initialUrl = window.location;
container,
router,
}: RouteRenderResult) => {
const initialUrl = router.state.location.pathname;

const openDialog = async () => {
await act(async () => {
clickButton('Open modal', getByRole);
});

// Load data
await waitForData('Loading data...', queryByText);
await waitFor(() =>
expect(container.querySelector('.ui.modal.active.visible')).toBeTruthy(),
);
};

const closeDialogButton = async (buttonCaption: string) => {
await act(async () => {
clickButton(buttonCaption, getByRole);

await waitForUrl(initialUrl.pathname);
await waitForUrl(initialUrl, router);
});
};

const closeDialogText = async (text: string) => {
await act(async () => {
expect(fireEvent.click(getByText(text))).toBeTruthy();
await waitForUrl(initialUrl.pathname);
await waitForUrl(initialUrl, router);
});
};

Expand Down
2 changes: 2 additions & 0 deletions src/tests/test-containers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,5 @@ export const renderRoutes = (routes: RouteObject[], options: RenderOptions) => {
router,
};
};

export type RouteRenderResult = ReturnType<typeof renderRoutes>;
Loading

0 comments on commit 304b194

Please sign in to comment.