vega-frontend-monorepo/apps/trading/components/sidebar/sidebar.spec.tsx

200 lines
5.4 KiB
TypeScript

import { act, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {
Sidebar,
SidebarButton,
SidebarContent,
ViewType,
useSidebar,
} from './sidebar';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
import { VegaIconNames } from '@vegaprotocol/ui-toolkit';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { Routes as AppRoutes } from '../../lib/links';
jest.mock('../node-health', () => ({
NodeHealthContainer: () => <span data-testid="node-health" />,
}));
jest.mock('@vegaprotocol/accounts', () => ({
TransferContainer: () => <div data-testid="transfer" />,
}));
jest.mock('@vegaprotocol/deposits', () => ({
DepositContainer: () => <div data-testid="deposit" />,
}));
jest.mock('../settings', () => ({
Settings: () => <div data-testid="settings" />,
}));
jest.mock('../welcome-dialog', () => ({
GetStarted: () => <div data-testid="get-started" />,
}));
const walletContext = {
pubKeys: [{ publicKey: 'pubkey' }],
} as VegaWalletContextShape;
describe('Sidebar', () => {
beforeEach(() => {
useSidebar.setState({ views: {} });
});
it('renders options prop', () => {
render(
<VegaWalletContext.Provider value={walletContext}>
<MemoryRouter>
<Sidebar options={<div data-testid="options" />} />
</MemoryRouter>
</VegaWalletContext.Provider>
);
expect(screen.getByTestId(ViewType.ViewAs)).toBeInTheDocument();
expect(screen.getByTestId(ViewType.Settings)).toBeInTheDocument();
expect(screen.getByTestId('node-health')).toBeInTheDocument();
expect(screen.getByTestId('options')).toBeInTheDocument();
});
it('renders selected state', async () => {
const routeId = '/markets/ABC';
render(
<VegaWalletContext.Provider value={walletContext}>
<MemoryRouter initialEntries={[routeId]}>
<Sidebar
options={
<SidebarButton
view={ViewType.Deposit}
icon={VegaIconNames.DEPOSIT}
tooltip="Deposit"
routeId={'/markets/:marketId'}
/>
}
/>
</MemoryRouter>
</VegaWalletContext.Provider>
);
const settingsButton = screen.getByTestId(ViewType.Settings);
const depositButton = screen.getByTestId(ViewType.Deposit);
// select settings first
await userEvent.click(settingsButton);
expect(settingsButton).toHaveClass('bg-vega-yellow text-black');
// switch to deposit
await userEvent.click(depositButton);
expect(settingsButton).not.toHaveClass('bg-vega-yellow text-black');
expect(depositButton).toHaveClass('bg-vega-yellow text-black');
// close order
await userEvent.click(depositButton);
expect(depositButton).not.toHaveClass('bg-vega-yellow text-black');
});
});
describe('SidebarContent', () => {
beforeEach(() => {
useSidebar.setState({ views: {} });
});
it('renders the correct content', () => {
const { container } = render(
<VegaWalletContext.Provider value={walletContext}>
<MemoryRouter initialEntries={['/markets/ABC']}>
<Routes>
<Route
path="/markets/:marketId"
id={AppRoutes.MARKET}
element={<SidebarContent />}
/>
</Routes>
</MemoryRouter>
</VegaWalletContext.Provider>
);
expect(container).toBeEmptyDOMElement();
act(() => {
useSidebar.setState({
views: { [AppRoutes.MARKET]: { type: ViewType.Transfer } },
});
});
expect(screen.getByTestId('transfer')).toBeInTheDocument();
act(() => {
useSidebar.setState({
views: { [AppRoutes.MARKET]: { type: ViewType.Deposit } },
});
});
expect(screen.getByTestId('deposit')).toBeInTheDocument();
});
it('closes sidebar if market id is required but not present', () => {
const { container } = render(
<VegaWalletContext.Provider value={walletContext}>
<MemoryRouter initialEntries={['/portfolio']}>
<Routes>
<Route
path="/portfolio"
id={AppRoutes.PORTFOLIO}
element={<SidebarContent />}
/>
</Routes>
</MemoryRouter>
</VegaWalletContext.Provider>
);
act(() => {
useSidebar.setState({
views: { [AppRoutes.PORTFOLIO]: { type: ViewType.Order } },
});
});
expect(container).toBeEmptyDOMElement();
act(() => {
useSidebar.setState({
views: { [AppRoutes.PORTFOLIO]: { type: ViewType.Settings } },
});
});
expect(screen.getByTestId('settings')).toBeInTheDocument();
act(() => {
useSidebar.setState({
views: { [AppRoutes.PORTFOLIO]: { type: ViewType.Info } },
});
});
expect(container).toBeEmptyDOMElement();
});
});
describe('SidebarButton', () => {
it.each([ViewType.Info, ViewType.Deposit, ViewType.ViewAs])(
'runs given callback regardless of requested view (%s)',
async (view) => {
const onClick = jest.fn();
render(
<SidebarButton
icon={VegaIconNames.INFO}
tooltip="INFO"
onClick={onClick}
view={view}
routeId="current-route-id"
/>
);
const btn = screen.getByTestId(view);
await userEvent.click(btn);
expect(onClick).toBeCalled();
}
);
});