feat: add pages tests
This commit is contained in:
parent
8db726a505
commit
9ed5af6857
20
__spec__/custon-renders.tsx
Normal file
20
__spec__/custon-renders.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { createMemoryRouter, RouterProvider } from 'react-router-dom';
|
||||
|
||||
import { render } from './utils';
|
||||
|
||||
export const renderWithProvider = (Component: ReactNode) => {
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
element: Component,
|
||||
},
|
||||
];
|
||||
|
||||
const router = createMemoryRouter(routes, {
|
||||
initialEntries: ['/'],
|
||||
initialIndex: 0,
|
||||
});
|
||||
|
||||
return render(<RouterProvider router={router} />);
|
||||
};
|
||||
@ -9,11 +9,12 @@ const config: Config = {
|
||||
'<rootDir>src',
|
||||
'<rootDir>',
|
||||
],
|
||||
rootDir: './',
|
||||
verbose: true,
|
||||
preset: 'ts-jest/presets/js-with-ts',
|
||||
moduleNameMapper: {
|
||||
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
|
||||
'./configs/jest/__mocks__/fileMock.ts',
|
||||
'<rootDir>/configs/jest/__mocks__/fileMock.ts',
|
||||
'\\.(css|less|scss)$': 'identity-obj-proxy',
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
import { screen, render } from '@testing-library/react';
|
||||
|
||||
import MoneyControllApp from './MoneyControllApp.ui';
|
||||
|
||||
describe('Test MoneyControllApp', () => {
|
||||
test('Render MoneyControllApp', () => {
|
||||
render(<MoneyControllApp />);
|
||||
|
||||
const appElem = screen.getByTestId('money-contoll-app');
|
||||
expect(appElem).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
32
src/pages/AnalyzePage/ui/AnalyzePage.spec.tsx
Normal file
32
src/pages/AnalyzePage/ui/AnalyzePage.spec.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import AnalyzePage from './AnalyzePage.ui';
|
||||
import AnalyzePageToolbar from './AnalyzePageToolbar.ui';
|
||||
|
||||
describe('Test AnalyzePage', () => {
|
||||
const setup = () => render(
|
||||
<AnalyzePage data-testid="analyze-page" />,
|
||||
);
|
||||
|
||||
test('should render correctly', () => {
|
||||
setup();
|
||||
|
||||
const pageElem = screen.getByTestId('analyze-page');
|
||||
expect(pageElem).toBeVisible();
|
||||
expect(pageElem).toHaveTextContent('Analyze page');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test AnalyzePageToolbar', () => {
|
||||
const setup = () => render(
|
||||
<AnalyzePageToolbar data-testid="analyze-page-toolbar" />,
|
||||
);
|
||||
|
||||
test('should render correctly', () => {
|
||||
setup();
|
||||
|
||||
const toolbarElem = screen.getByTestId('analyze-page-toolbar');
|
||||
expect(toolbarElem).toBeVisible();
|
||||
expect(toolbarElem).toHaveTextContent('Analyze Page Toolbar');
|
||||
});
|
||||
});
|
||||
@ -1,7 +1,8 @@
|
||||
import type { FC } from 'react';
|
||||
import type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';
|
||||
|
||||
const AnalyzePage: FC = () => (
|
||||
<div>
|
||||
type AnalyzePageProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
||||
const AnalyzePage: FC<AnalyzePageProps> = (props) => (
|
||||
<div {...props}>
|
||||
Analyze page
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
const AnalyzePageToolbar = () => (
|
||||
<Toolbar>
|
||||
import type { ToolbarProps } from '@mui/material/Toolbar/Toolbar';
|
||||
import type { FC } from 'react';
|
||||
|
||||
type AnalyzePageToolbarProps = ToolbarProps;
|
||||
const AnalyzePageToolbar: FC<AnalyzePageToolbarProps> = (props) => (
|
||||
<Toolbar {...props}>
|
||||
<Typography noWrap component="div" variant="h6">
|
||||
Analyze Page Toolbar
|
||||
</Typography>
|
||||
|
||||
52
src/pages/ErrorPage/ui/ErrorPage.spec.tsx
Normal file
52
src/pages/ErrorPage/ui/ErrorPage.spec.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { ErrorPageToolbar } from 'pages/ErrorPage';
|
||||
import type { ErrorPageToolbarProps } from 'pages/ErrorPage/ui/ErrorPageToolbar.ui';
|
||||
|
||||
import ErrorPage from './ErrorPage.ui';
|
||||
|
||||
import type { ErrorPageProps } from './ErrorPage.ui';
|
||||
|
||||
describe('Test ErrorPage', () => {
|
||||
const setup = (props?: Partial<ErrorPageProps>) => render(
|
||||
<ErrorPage data-testid="error-page" {...props} />,
|
||||
);
|
||||
|
||||
test('should render ErrorBoundary', () => {
|
||||
setup();
|
||||
|
||||
const pageElem = screen.getByTestId('error-page');
|
||||
expect(pageElem).toBeVisible();
|
||||
expect(pageElem).toHaveTextContent('Что-то пошло не так');
|
||||
});
|
||||
|
||||
test('should render 404', () => {
|
||||
setup({ type: '404' });
|
||||
|
||||
const pageElem = screen.getByTestId('error-page');
|
||||
expect(pageElem).toBeVisible();
|
||||
expect(pageElem).not.toHaveTextContent('Что-то пошло не так');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test ErrorPageToolbar', () => {
|
||||
const setup = (props?: Partial<ErrorPageToolbarProps>) => render(
|
||||
<ErrorPageToolbar data-testid="error-page-toolbar" {...props} />,
|
||||
);
|
||||
|
||||
test('should render ErrorBoundary', () => {
|
||||
setup();
|
||||
|
||||
const toolbarElem = screen.getByTestId('error-page-toolbar');
|
||||
expect(toolbarElem).toBeVisible();
|
||||
expect(toolbarElem).toHaveTextContent('Непредвиденная ошибка');
|
||||
});
|
||||
|
||||
test('should render 404', () => {
|
||||
setup({ type: '404' });
|
||||
|
||||
const toolbarElem = screen.getByTestId('error-page-toolbar');
|
||||
expect(toolbarElem).toBeVisible();
|
||||
expect(toolbarElem).toHaveTextContent('Страницы не существует');
|
||||
});
|
||||
});
|
||||
@ -4,14 +4,16 @@ import Typography from '@mui/material/Typography';
|
||||
import _404Image from 'public/assets/images/404.png';
|
||||
import OopsImage from 'public/assets/images/oops.png';
|
||||
|
||||
import type { GridProps } from '@mui/material/Grid/Grid';
|
||||
import type { FC } from 'react';
|
||||
|
||||
type ErrorPageProps = {
|
||||
export type ErrorPageProps = GridProps & {
|
||||
type?: '404' | 'ErrorBoundary';
|
||||
};
|
||||
const ErrorPage: FC<ErrorPageProps> = (props) => {
|
||||
const {
|
||||
type = 'ErrorBoundary',
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
if (type === 'ErrorBoundary') {
|
||||
@ -22,6 +24,7 @@ const ErrorPage: FC<ErrorPageProps> = (props) => {
|
||||
direction="column"
|
||||
justifyContent="center"
|
||||
rowGap={5}
|
||||
{...restProps}
|
||||
>
|
||||
<Grid item>
|
||||
<Typography variant="h5">
|
||||
@ -37,7 +40,7 @@ const ErrorPage: FC<ErrorPageProps> = (props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid container justifyContent="center">
|
||||
<Grid container justifyContent="center" {...restProps}>
|
||||
<Grid item>
|
||||
<img alt="asd" src={_404Image} />
|
||||
</Grid>
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
import type { ToolbarProps } from '@mui/material/Toolbar/Toolbar';
|
||||
import type { FC } from 'react';
|
||||
|
||||
type ErrorPageToolbarProps = {
|
||||
export type ErrorPageToolbarProps = ToolbarProps & {
|
||||
type?: '404' | 'ErrorBoundary';
|
||||
};
|
||||
|
||||
@ -15,10 +16,11 @@ const TITLE: Record<NonNullable<ErrorPageToolbarProps['type']>, string> = {
|
||||
const ErrorPageToolbar: FC<ErrorPageToolbarProps> = (props) => {
|
||||
const {
|
||||
type = 'ErrorBoundary',
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Toolbar>
|
||||
<Toolbar {...restProps}>
|
||||
<Typography noWrap component="div" variant="h6">
|
||||
{TITLE[type]}
|
||||
</Typography>
|
||||
|
||||
35
src/pages/PaymentsPage/ui/PaymentsPage.spec.tsx
Normal file
35
src/pages/PaymentsPage/ui/PaymentsPage.spec.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import PaymentsPage from './PaymentsPage.ui';
|
||||
import PaymentsPageToolbar from './PaymentsPageToolbar.ui';
|
||||
|
||||
import type { PaymentsPageProps } from './PaymentsPage.ui';
|
||||
import type { PaymentsPageToolbarProps } from './PaymentsPageToolbar.ui';
|
||||
|
||||
describe('Test PaymentsPage', () => {
|
||||
const setup = (props?: Partial<PaymentsPageProps>) => render(
|
||||
<PaymentsPage data-testid="payments-page" {...props} />,
|
||||
);
|
||||
|
||||
test('should render correctly', () => {
|
||||
setup();
|
||||
|
||||
const pageElem = screen.getByTestId('payments-page');
|
||||
expect(pageElem).toBeVisible();
|
||||
expect(pageElem).toHaveTextContent('Payments Page');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test PaymentsPageToolbar', () => {
|
||||
const setup = (props?: Partial<PaymentsPageToolbarProps>) => render(
|
||||
<PaymentsPageToolbar data-testid="payments-page-toolbar" {...props} />,
|
||||
);
|
||||
|
||||
test('should render correctly', () => {
|
||||
setup();
|
||||
|
||||
const toolbarElem = screen.getByTestId('payments-page-toolbar');
|
||||
expect(toolbarElem).toBeVisible();
|
||||
expect(toolbarElem).toHaveTextContent('Payments Page Toolbar');
|
||||
});
|
||||
});
|
||||
@ -1,7 +1,8 @@
|
||||
import type { FC } from 'react';
|
||||
import type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';
|
||||
|
||||
const PaymentsPage: FC = () => (
|
||||
<div>
|
||||
export type PaymentsPageProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
||||
const PaymentsPage: FC<PaymentsPageProps> = (props) => (
|
||||
<div {...props}>
|
||||
Payments Page
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
import type { ToolbarProps } from '@mui/material/Toolbar/Toolbar';
|
||||
import type { FC } from 'react';
|
||||
|
||||
const PaymentsPageToolbar: FC = () => (
|
||||
<Toolbar>
|
||||
export type PaymentsPageToolbarProps = ToolbarProps;
|
||||
const PaymentsPageToolbar: FC<PaymentsPageToolbarProps> = (props) => (
|
||||
<Toolbar {...props}>
|
||||
<Typography noWrap component="div" variant="h6">
|
||||
Payments Page Toolbar
|
||||
</Typography>
|
||||
|
||||
31
src/pages/SchedulePage/ui/SchedulePage.spec.tsx
Normal file
31
src/pages/SchedulePage/ui/SchedulePage.spec.tsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { SchedulePage, SchedulePageToolbar } from 'pages/SchedulePage';
|
||||
|
||||
describe('Test SchedulePage', () => {
|
||||
const setup = () => render(
|
||||
<SchedulePage data-testid="schedule-page" />,
|
||||
);
|
||||
|
||||
test('should render correctly', () => {
|
||||
setup();
|
||||
|
||||
const pageElem = screen.getByTestId('schedule-page');
|
||||
expect(pageElem).toBeVisible();
|
||||
expect(pageElem).toHaveTextContent('Schedule Page');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test SchedulePageToolabr', () => {
|
||||
const setup = () => render(
|
||||
<SchedulePageToolbar data-testid="schedule-page-toolbar" />,
|
||||
);
|
||||
|
||||
test('should render correctly', () => {
|
||||
setup();
|
||||
|
||||
const toolbarElem = screen.getByTestId('schedule-page-toolbar');
|
||||
expect(toolbarElem).toBeVisible();
|
||||
expect(toolbarElem).toHaveTextContent('Schedule Page Toolbar');
|
||||
});
|
||||
});
|
||||
@ -1,7 +1,8 @@
|
||||
import type { FC } from 'react';
|
||||
import type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';
|
||||
|
||||
const SchedulePage: FC = () => (
|
||||
<div>
|
||||
export type SchedulePageProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
||||
const SchedulePage: FC<SchedulePageProps> = (props) => (
|
||||
<div {...props}>
|
||||
Schedule Page
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
import type { ToolbarProps } from '@mui/material/Toolbar/Toolbar';
|
||||
import type { FC } from 'react';
|
||||
|
||||
const SchedulePageToolbar: FC = () => (
|
||||
<Toolbar>
|
||||
type SchedulePageToolbarProps = ToolbarProps;
|
||||
const SchedulePageToolbar: FC<SchedulePageToolbarProps> = (props) => (
|
||||
<Toolbar {...props}>
|
||||
<Typography noWrap component="div" variant="h6">
|
||||
Schedule Page Toolbar
|
||||
</Typography>
|
||||
|
||||
116
src/widgets/AsideMenuLayout/ui/AsideMenuLayout.spec.tsx
Normal file
116
src/widgets/AsideMenuLayout/ui/AsideMenuLayout.spec.tsx
Normal file
@ -0,0 +1,116 @@
|
||||
import { renderWithProvider } from '__spec__/custon-renders';
|
||||
|
||||
import PieChartIcon from '@mui/icons-material/PieChart';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
|
||||
import AsideMenuLayout from './AsideMenuLayout.ui';
|
||||
|
||||
const toggleSwitcher = (testId = 'drawer-switcher') => {
|
||||
const switcherElem = screen.getByTestId(testId);
|
||||
fireEvent.click(switcherElem);
|
||||
};
|
||||
|
||||
describe('Test AsideMenuLayout', () => {
|
||||
const setup = () => {
|
||||
const Content = () => (
|
||||
<div>
|
||||
Test Content
|
||||
</div>
|
||||
);
|
||||
|
||||
const Toolbar = () => (
|
||||
<div>
|
||||
Test Toolbar
|
||||
</div>
|
||||
);
|
||||
|
||||
const pages = [
|
||||
{
|
||||
icon: <PieChartIcon />,
|
||||
title: 'Test Route',
|
||||
path: '/test-route',
|
||||
},
|
||||
{
|
||||
icon: <PieChartIcon />,
|
||||
title: 'Another Test Route',
|
||||
path: '/another-test-route',
|
||||
},
|
||||
];
|
||||
|
||||
return renderWithProvider(
|
||||
<AsideMenuLayout
|
||||
Content={<Content />}
|
||||
data-testid="aside-menu-layout"
|
||||
DrawerSwitcherProps={{
|
||||
// @ts-ignore
|
||||
'data-testid': 'drawer-switcher',
|
||||
}}
|
||||
pages={pages}
|
||||
Toolbar={<Toolbar />}
|
||||
/>,
|
||||
);
|
||||
};
|
||||
|
||||
test('should render correctly', () => {
|
||||
setup();
|
||||
|
||||
const layoutElem = screen.getByTestId('aside-menu-layout');
|
||||
expect(layoutElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should render toolbar', () => {
|
||||
setup();
|
||||
|
||||
const toolbarElem = screen.getByText('Test Toolbar');
|
||||
expect(toolbarElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should render content', () => {
|
||||
setup();
|
||||
|
||||
const toolbarElem = screen.getByText('Test Content');
|
||||
expect(toolbarElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should render navigation routes', () => {
|
||||
setup();
|
||||
|
||||
const linkElem = screen.getByText('Test Route');
|
||||
expect(linkElem).toBeVisible();
|
||||
|
||||
const anotherLinkElem = screen.getByText('Another Test Route');
|
||||
expect(anotherLinkElem).toBeVisible();
|
||||
});
|
||||
|
||||
describe('Test switch open/close drawer', () => {
|
||||
test('should have correct close icon', () => {
|
||||
setup();
|
||||
|
||||
const closeIconElem = screen.getByTestId('ChevronLeftIcon');
|
||||
expect(closeIconElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should have correct open icon', () => {
|
||||
setup();
|
||||
toggleSwitcher();
|
||||
|
||||
const openIconElem = screen.getByTestId('MenuIcon');
|
||||
expect(openIconElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should show link text', () => {
|
||||
setup();
|
||||
|
||||
const linkTextElem = screen.getByText('Test Route');
|
||||
expect(linkTextElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should hide link text', () => {
|
||||
setup();
|
||||
toggleSwitcher();
|
||||
|
||||
const linkTextElem = screen.queryByText('Test Route');
|
||||
expect(linkTextElem).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -10,23 +10,32 @@ import AppBar from './components/AppBar';
|
||||
import Drawer from './components/Drawer';
|
||||
import DrawerHeader from './components/DrawerMenu';
|
||||
import DrawerSwitcher from './components/DrawerSwitcher';
|
||||
import MenuItem from './components/MenuItem';
|
||||
import MenuItem from './components/MenuItem/MenuItem.ui';
|
||||
|
||||
import type { MenuItemProps } from './components/MenuItem';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import type { MenuItemProps } from './components/MenuItem/MenuItem.ui';
|
||||
import type { BoxProps } from '@mui/material/Box/Box';
|
||||
import type {
|
||||
FC,
|
||||
ReactNode,
|
||||
DetailedHTMLProps,
|
||||
HTMLAttributes,
|
||||
} from 'react';
|
||||
|
||||
const drawerWidth = 250;
|
||||
|
||||
type AsideMenuLayoutProps = {
|
||||
type AsideMenuLayoutProps = BoxProps & {
|
||||
pages: MenuItemProps['page'][];
|
||||
Content: ReactNode;
|
||||
Toolbar?: ReactNode;
|
||||
DrawerSwitcherProps?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
||||
};
|
||||
const AsideMenuLayout: FC<AsideMenuLayoutProps> = (props) => {
|
||||
const {
|
||||
pages,
|
||||
Content,
|
||||
Toolbar,
|
||||
DrawerSwitcherProps,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const [isOpen, setIsOpen] = useState(true);
|
||||
@ -39,7 +48,7 @@ const AsideMenuLayout: FC<AsideMenuLayoutProps> = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Box sx={{ display: 'flex' }}>
|
||||
<Box sx={{ display: 'flex' }} {...restProps}>
|
||||
<CssBaseline />
|
||||
|
||||
<Drawer
|
||||
@ -51,6 +60,7 @@ const AsideMenuLayout: FC<AsideMenuLayoutProps> = (props) => {
|
||||
<DrawerSwitcher
|
||||
open={isOpen}
|
||||
onClick={isOpen ? handleDrawerClose : handleDrawerOpen}
|
||||
{...DrawerSwitcherProps}
|
||||
>
|
||||
{ isOpen ? <ChevronLeftIcon /> : <MenuIcon /> }
|
||||
</DrawerSwitcher>
|
||||
|
||||
@ -8,7 +8,7 @@ type AppBarProps = MuiAppBarProps & {
|
||||
drawerWidth: number;
|
||||
};
|
||||
|
||||
const AppBar = styled(MuiAppBar, { shouldForwardProp: (prop) => prop !== 'open' })<AppBarProps>(
|
||||
const AppBar = styled(MuiAppBar, { shouldForwardProp: (prop) => !['open', 'drawerWidth'].includes(prop as string) })<AppBarProps>(
|
||||
({ theme, open, drawerWidth }) => ({
|
||||
transition: theme.transitions.create(['width', 'margin'], {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
|
||||
@ -24,7 +24,7 @@ const closedMixin = (theme: Theme): CSSObject => ({
|
||||
width: `calc(${theme.spacing(8)} + 1px)`,
|
||||
});
|
||||
|
||||
const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })<DrawerProps>(
|
||||
const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => !['open', 'drawerWidth'].includes(prop as string) })<DrawerProps>(
|
||||
({ theme, open, drawerWidth }) => ({
|
||||
width: drawerWidth,
|
||||
flexShrink: 0,
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
import { renderWithProvider } from '__spec__/custon-renders';
|
||||
|
||||
import PieChartIcon from '@mui/icons-material/PieChart';
|
||||
import { screen } from '@testing-library/react';
|
||||
|
||||
import MenuItem from './MenuItem.ui';
|
||||
|
||||
import type { MenuItemProps } from './MenuItem.ui';
|
||||
|
||||
describe('MenuItem', () => {
|
||||
const setup = (props?: Partial<MenuItemProps>) => renderWithProvider(
|
||||
<MenuItem
|
||||
data-testid="menu-item"
|
||||
NavLinkProps={{
|
||||
// @ts-ignore
|
||||
'data-testid': 'menu-item-link',
|
||||
}}
|
||||
page={{
|
||||
icon: <PieChartIcon />,
|
||||
title: 'Test Route',
|
||||
path: '/test-route',
|
||||
}}
|
||||
{...props}
|
||||
/>,
|
||||
);
|
||||
|
||||
test('should render', () => {
|
||||
setup();
|
||||
|
||||
const itemElem = screen.getByTestId('menu-item');
|
||||
expect(itemElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should render correct text', () => {
|
||||
setup();
|
||||
|
||||
const textElem = screen.getByText('Test Route');
|
||||
expect(textElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should render correct icon', () => {
|
||||
setup();
|
||||
|
||||
const iconElem = screen.getByTestId('PieChartIcon');
|
||||
expect(iconElem).toBeVisible();
|
||||
});
|
||||
|
||||
test('should have correct href', () => {
|
||||
setup();
|
||||
|
||||
const itemElem = screen.getByTestId('menu-item-link');
|
||||
expect(itemElem).toHaveAttribute('href', '/test-route');
|
||||
});
|
||||
|
||||
describe('Test closed MenuItem', () => {
|
||||
test('should not render text if closed', () => {
|
||||
setup({ isOpen: false });
|
||||
|
||||
const textElem = screen.getByText('Test Route');
|
||||
expect(textElem).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('should render correct icon if closed', () => {
|
||||
setup({ isOpen: false });
|
||||
|
||||
const iconElem = screen.getByTestId('PieChartIcon');
|
||||
expect(iconElem).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -6,7 +6,9 @@ import { styled, useTheme } from '@mui/material/styles';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { NavLink as RRDNavLink } from 'react-router-dom';
|
||||
|
||||
import type { ListItemProps } from '@mui/material/ListItem/ListItem';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import type { NavLinkProps } from 'react-router-dom';
|
||||
|
||||
const NavLink = styled(RRDNavLink)(({ theme }) => ({
|
||||
textDecoration: 'none',
|
||||
@ -14,25 +16,28 @@ const NavLink = styled(RRDNavLink)(({ theme }) => ({
|
||||
width: '100%',
|
||||
}));
|
||||
|
||||
export type MenuItemProps = {
|
||||
export type MenuItemProps = ListItemProps & {
|
||||
page: {
|
||||
icon: ReactNode;
|
||||
title: string;
|
||||
path: string;
|
||||
};
|
||||
isOpen: boolean;
|
||||
isOpen?: boolean;
|
||||
NavLinkProps?: NavLinkProps;
|
||||
};
|
||||
|
||||
const MenuItem: FC<MenuItemProps> = (props) => {
|
||||
const {
|
||||
page,
|
||||
isOpen,
|
||||
isOpen = true,
|
||||
NavLinkProps,
|
||||
...restProps
|
||||
} = props;
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<ListItem disablePadding>
|
||||
<NavLink to={page.path}>
|
||||
<ListItem disablePadding {...restProps}>
|
||||
<NavLink to={page.path} {...NavLinkProps}>
|
||||
{({ isActive }) => (
|
||||
<ListItemButton
|
||||
sx={{
|
||||
Loading…
x
Reference in New Issue
Block a user