CFE-6 Merge branch 'develop' into 'bugfix/CFE-6_fix_toas_containers'

This commit is contained in:
AmirHossein Mahmoodi
2023-10-31 11:52:42 +00:00
44 changed files with 1076 additions and 137 deletions

View File

@@ -0,0 +1,43 @@
import {render, screen, waitFor} from "@testing-library/react";
import MockAppWithProviders from "../../../../../../../../../../../mocks/AppWithProvider";
import {AnswersProvider} from "@/lib/callWidget/contexts/answers";
import ActionHeader from "..";
const tab = {
active: true,
active_category_id: 1,
phone_number : "09134849737"
}
describe('Action Header Button from Call Actions Categories', () => {
describe('Rendering', () => {
it('should see header text', async () => {
render(
<MockAppWithProviders>
<AnswersProvider>
<ActionHeader tab={tab} />
</AnswersProvider>
</MockAppWithProviders>
)
const headingElement = screen.getByRole('heading', {
name: /\.\.\.\. عملیات های مربوط به تماس:/i
})
await waitFor(() => {
expect(headingElement).toBeInTheDocument()
})
});
it('should see phone number', async () => {
render(
<MockAppWithProviders>
<AnswersProvider>
<ActionHeader tab={tab} />
</AnswersProvider>
</MockAppWithProviders>
)
const phone_numberElement = screen.queryByText(/09134849737/i)
await waitFor(() => {
expect(phone_numberElement).toBeInTheDocument()
})
});
});
});

View File

@@ -0,0 +1,25 @@
import {useTranslations} from "next-intl";
import {Stack, Typography} from "@mui/material";
const ActionHeader = ({tab}) => {
const t = useTranslations();
return (
<Stack sx={{
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
py: 2,
backgroundColor: "primary.main",
overflow: "hidden"
}}>
<Typography variant="subtitle1" sx={{marginRight: 1, color: "#fff"}}>
.... {t("CallAction.call_history_of")}:
</Typography>
<Typography data-testid="phone_number" variant="subtitle1" sx={{color: "#fff"}}>
{tab.phone_number} ....
</Typography>
</Stack>
)
}
export default ActionHeader

View File

@@ -0,0 +1,25 @@
import { Button, Grid } from "@mui/material";
import useCategories from "@/lib/callWidget/hooks/useCategories";
const CallActionCategoriesButton = ({ category, tab }) => {
const { setActiveCategoryID } = useCategories();
return (
<Grid item xs={4}>
<Button
sx={{py : 1.5}}
fullWidth
variant={"contained"}
color={tab.active_category_id === category.category_id ? "primary" : "inherit"}
onClick={() => {
setActiveCategoryID(tab.id, category.category_id);
}}
>
{category.category_name}
</Button>
</Grid>
);
};
export default CallActionCategoriesButton;

View File

@@ -0,0 +1,51 @@
import {fireEvent, render, screen, waitFor} from "@testing-library/react";
import MockAppWithProviders from "../../../../../../../../../../../mocks/AppWithProvider";
import {AnswersProvider} from "@/lib/callWidget/contexts/answers";
import CallActionCategoriesButton from "../CallActionCategoriesButton";
const category = {
category_id: 1,
category_name: "اطلاعات راه ها",
}
const tab = {
active: true,
active_category_id: 1,
}
describe('Call Action Categories Button from Call Actions Categories', () => {
describe('Rendering', () => {
it('should categories names', async () => {
render(
<MockAppWithProviders>
<AnswersProvider>
<CallActionCategoriesButton tab={tab} category={category}/>
</AnswersProvider>
</MockAppWithProviders>
)
const categoryElement = screen.queryByText("اطلاعات راه ها")
await waitFor(() => {
expect(categoryElement).toBeInTheDocument()
})
});
});
describe("Behavior", ()=>{
it("Should change the color when button clecked",async()=>{
render(
<MockAppWithProviders>
<AnswersProvider>
<CallActionCategoriesButton tab={tab} category={category}/>
</AnswersProvider>
</MockAppWithProviders>
)
const buttonElement = screen.getByRole('button', {
name: /اطلاعات راه ها/i
})
fireEvent.click(buttonElement);
await waitFor(() => {
expect(buttonElement).toHaveStyle('background-color: rgb(12, 31, 23)');
})
})
})
})

View File

@@ -0,0 +1,29 @@
import { AnswersProvider } from "@/lib/callWidget/contexts/answers";
import CallActionsCategories from "..";
import MockAppWithProviders from "../../../../../../../../../../../mocks/AppWithProvider";
import { render, screen, waitFor } from "@testing-library/react";
const tab = {
active: true,
active_category_id: 1,
id : 1,
phone_number : "09134849737"
}
describe('Call Action Categories Button from Call Actions Categories', () => {
describe('Rendering', () => {
it('should see divider text', async () => {
render(
<MockAppWithProviders>
<AnswersProvider>
<CallActionsCategories tab={tab}/>
</AnswersProvider>
</MockAppWithProviders>
)
const divider_textElement = screen.queryByText("موضوع ها")
await waitFor(() => {
expect(divider_textElement).toBeInTheDocument()
})
});
});
})

View File

@@ -0,0 +1,22 @@
import { Chip, Divider, Grid, Stack } from "@mui/material";
import useCategories from "@/lib/callWidget/hooks/useCategories";
import CallActionCategoriesButton from "./CallActionCategoriesButton";
import { useTranslations } from "next-intl";
const CallActionsCategories = ({ tab }) => {
const { categoryLists } = useCategories();
const t = useTranslations();
return (
<>
<Divider sx={{margin : 2}}><Chip label={t("CallAction.categories")} variant="outlined"/></Divider>
<Stack sx={{m : 1, p : 1}} direction={"row"}>
<Grid container spacing={2}>
{categoryLists.map((category) => {
return <CallActionCategoriesButton tab={tab} key={category.category_id} category={category} />;
})}
</Grid>
</Stack>
</>
);
};
export default CallActionsCategories;

View File

@@ -0,0 +1,54 @@
import {fireEvent, render, screen, waitFor} from "@testing-library/react";
import MockAppWithProviders from "../../../../../../../../../../../mocks/AppWithProvider";
import {AnswersProvider} from "@/lib/callWidget/contexts/answers";
import CallActionDescription from "..";
describe('Action Header Button from Call Actions Categories', () => {
describe('Rendering', () => {
it('should see placeholder text', async () => {
render(
<MockAppWithProviders>
<AnswersProvider>
<CallActionDescription />
</AnswersProvider>
</MockAppWithProviders>
)
const textElement = screen.getByPlaceholderText('لطفا توضیحات خود را وارد نمایید')
await waitFor(() => {
expect(textElement).toBeInTheDocument()
})
});
it('should see header text', async () => {
render(
<MockAppWithProviders>
<AnswersProvider>
<CallActionDescription />
</AnswersProvider>
</MockAppWithProviders>
)
const textElement = screen.getByText('توضیحات تماس (اختیاری)')
await waitFor(() => {
expect(textElement).toBeInTheDocument()
})
});
});
describe("Behavior", ()=>{
it("Should see what write in input", async()=>{
const setDescription = jest.fn();
render(
<MockAppWithProviders>
<AnswersProvider>
<CallActionDescription setDescription={setDescription} />
</AnswersProvider>
</MockAppWithProviders>
)
const textElement = screen.getByPlaceholderText('لطفا توضیحات خود را وارد نمایید')
fireEvent.change(textElement, {target : {value : "امین"}})
await waitFor(() => {
expect(textElement).toHaveValue("امین")
})
})
})
});

View File

@@ -0,0 +1,27 @@
import { Box, Chip, Divider, TextField } from "@mui/material"
import { useTranslations } from "next-intl";
const CallActionDescription = ({setDescription}) => {
const t = useTranslations();
return(
<>
<Divider sx={{margin : 2}}><Chip label={t("CallAction.description")} variant="outlined"/></Divider>
<Box sx={{m : 2}}>
<TextField
variant="outlined"
placeholder={t(
"CallAction.text_field_palacholder"
)}
type={"text"}
fullWidth
multiline
rows={8}
onChange={(e)=>{
setDescription(e.target.value)
}}
/>
</Box>
</>
)
}
export default CallActionDescription

View File

@@ -0,0 +1,14 @@
import { Button, Grid } from "@mui/material";
const CallActionSubcategoriesButton = ({ sub_category, tab, handleSubcategoryButton }) => {
return sub_category.category_id === tab.active_category_id ? (
<Grid item xs={3}>
<Button sx={{py : 1.5}} fullWidth color="inherit"
onClick={()=>{handleSubcategoryButton(sub_category.category_id, sub_category.subcategory_id)}} variant={"contained"}>
{sub_category.subcategory_name}
</Button>
</Grid>
) : null;
};
export default CallActionSubcategoriesButton;

View File

@@ -0,0 +1,37 @@
import {render, screen, waitFor} from "@testing-library/react";
import MockAppWithProviders from "../../../../../../../../../../../mocks/AppWithProvider";
import {AnswersProvider} from "@/lib/callWidget/contexts/answers";
import CallActionSubcategoriesButton from "../CallActionSubcategoriesButton";
const sub_category = {
category_id: 1,
category_name: "اطلاعات راه",
subcategory_id: 1,
subcategory_name: "اطلاعات باز و بسته"
};
const tab = {
active: true,
active_category_id: 1,
date: new Date(),
id: 1,
phone_number: "09134849737"
};
describe('Call Action Subcategories Button from Call Actions Categories', () => {
describe('Rendering', () => {
it('should render subcategory name', async () => {
render(
<MockAppWithProviders>
<AnswersProvider>
<CallActionSubcategoriesButton sub_category={sub_category} tab={tab} />
</AnswersProvider>
</MockAppWithProviders>
);
const subCategoryElement = screen.queryByText(/اطلاعات باز و بسته/i);
await waitFor(() => {
expect(subCategoryElement).toBeInTheDocument();
});
});
});
});

View File

@@ -0,0 +1,29 @@
import { AnswersProvider } from "@/lib/callWidget/contexts/answers";
import CallActionsSubcategories from "..";
import MockAppWithProviders from "../../../../../../../../../../../mocks/AppWithProvider";
import { render, screen, waitFor } from "@testing-library/react";
const tab = {
active: true,
active_category_id: 1,
id : 1,
phone_number : "09134849737"
}
describe('Call Action Categories Button from Call Actions Categories', () => {
describe('Rendering', () => {
it('should see divider text', async () => {
render(
<MockAppWithProviders>
<AnswersProvider>
<CallActionsSubcategories tab={tab}/>
</AnswersProvider>
</MockAppWithProviders>
)
const divider_textElement = screen.queryByText("زیر موضوع ها")
await waitFor(() => {
expect(divider_textElement).toBeInTheDocument()
})
});
});
})

View File

@@ -0,0 +1,22 @@
import useCategories from "@/lib/callWidget/hooks/useCategories";
import { Chip, Divider, Grid, Stack } from "@mui/material";
import CallActionSubcategoriesButton from "@/components/layouts/Dashboard/CallWidget/CallWidgetDialog/CallTabs/CallTabPanel/CallActions/CallActionSubcategories/CallActionSubcategoriesButton";
import { useTranslations } from "next-intl";
const CallActionsSubcategories = ({ tab, handleSubcategoryButton }) => {
const { subCategoryLists } = useCategories();
const t = useTranslations();
return (
<>
<Divider sx={{margin : 2}}><Chip label={t("CallAction.subcategories")} variant="outlined"/></Divider>
<Stack sx={{m : 1, p : 1 }} direction={"row"}>
<Grid container spacing={2}>
{subCategoryLists.map((sub_category, index) => {
return <CallActionSubcategoriesButton key={index} tab={tab} sub_category={sub_category} handleSubcategoryButton={handleSubcategoryButton}/>;
})}
</Grid>
</Stack>
</>
);
};
export default CallActionsSubcategories;

View File

@@ -1,7 +1,50 @@
const CallActions = ({tab}) => {
import CallActionsCategories from "./CallActionCategories";
import CallActionsSubcategories from "./CallActionSubcategories";
import ActionHeader from "./ActionHeader";
import CallActionDescription from "./CallActionDescription";
import {CALL_ACTION} from "@/core/data/apiRoutes";
import useRequest from "@/lib/app/hooks/useRequest";
import useAnswers from "@/lib/callWidget/hooks/useAnswers";
import {useState} from "react";
import {Stack} from "@mui/material";
function CallActions({tab}) {
const [description, setDescription] = useState('')
const requestServer = useRequest({auth: true});
const {closeAnswerTab} = useAnswers();
const handleSubcategoryButton = (category_id, subcategory_id) => {
requestServer(`${CALL_ACTION}/${tab.id}`, "post", {
data: {
category_id,
subcategory_id,
description
},
success: {
notification: {show: false},
},
})
.then(() => {
closeAnswerTab(tab.id);
})
.catch(() => {
});
};
return (
<>CallActions - {tab.id}</>
)
<Stack sx={{
height: "100%",
overflow: "hidden"
}}>
<ActionHeader tab={tab}/>
<Stack sx={{height: "100%", overflow: "scroll"}}>
<CallActionDescription setDescription={setDescription}/>
<CallActionsCategories tab={tab}/>
<CallActionsSubcategories handleSubcategoryButton={handleSubcategoryButton} tab={tab}/>
</Stack>
</Stack>
);
}
export default CallActions
export default CallActions;

View File

@@ -25,7 +25,7 @@ const CallHistory = ({tab}) => {
overflow: "hidden"
}}>
<HistoryHeader tab={tab}/>
<Stack sx={{overflow: "scroll"}}>
<Stack sx={{height: "100%", overflow: "scroll"}}>
{errorHistoryList ? (
<ErrorOrEmpty isErrorOrEmpty="error"/>
) : isLoadingHistoryList ? (

View File

@@ -7,7 +7,7 @@ const CallTabPanel = ({tab}) => {
<Grid container columns={{xs: 3}} sx={{display: !tab.active && 'none', height: '100%', overflow: "hidden"}}
role="tabpanel"
id={`answer-tabpanel-${tab.id}`} aria-labelledby={`answer-tab-${tab.id}`}>
<Grid item xs={2}>
<Grid item xs={2} sx={{height: "100%", overflow: "scroll"}}>
<CallActions tab={tab}/>
</Grid>
<Grid item>

View File

@@ -4,7 +4,7 @@ import SidebarList from "./SidebarList";
import useUser from "@/lib/app/hooks/useUser";
const SidebarDrawer = ({handleDrawerToggle}) => {
const {user} = useUser()
const {user} = useUser();
const t = useTranslations();
return (
<>

View File

@@ -10,29 +10,15 @@ function reducer(state, action) {
case "COLLAPSE_MENU":
return state.map((itemsArr) =>
itemsArr.map((item) =>
action.key == item.key
? {...item, showSubItem: !item.showSubItem}
: item
action.key === item.key ? { ...item, showSubItem: !item.showSubItem } : item
)
);
case "SELECTED":
return state.map((itemsArr) =>
itemsArr.map((item) => {
if (item.type === "page") {
if (action.route === item.route)
return {...item, selected: true}
else
return {...item, selected: false}
}
return {...item}
// item.subItem.map((subitem) => {
// if (action.route === subitem.route)
// return {...item, showSubItem: true, subItem: {...subitem, selected: true}}
// else
// return {...item, showSubItem: false, subItem: {...subitem, selected: false}}
// })
}
)
itemsArr.map((item) => ({
...item,
selected: item.type === "page" && action.route === item.route,
}))
);
default:
throw new Error();
@@ -54,7 +40,7 @@ export default function SidebarList({handleDrawerToggle}) {
<Fragment key={index}>
{itemArr.map((item) =>
<Fragment key={item.key}>
{(user.permissions.includes(item.permission) || item.permission === "all") &&
{(user?.permissions?.includes(item.permission) || item.permission === "all") &&
<SidebarListItem
item={item}
dispatch={dispatch}

View File

@@ -9,23 +9,27 @@ import useNotification from "@/lib/app/hooks/useNotification";
const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => {
const t = useTranslations();
const {notification_count} = useNotification()
const { notification_count } = useNotification();
const hasSubItems = item.type === "menu" && item.subItem && item.subItem.length > 0;
const renderBadge = () => (
<IconButton>
<Badge
badgeContent={notification_count ? notification_count[item.name] : 0}
color="error"
variant="standard"
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
/>
</IconButton>
);
return (
<>
<ListItem disablePadding secondaryAction={
<IconButton>
<Badge
badgeContent={notification_count ? notification_count[item.name] : 0}
color="error"
variant="standard"
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
/>
</IconButton>
}>
<ListItem disablePadding secondaryAction={renderBadge()}>
<ListItemButton
selected={item.selected}
{...(item.type == "page" && {
@@ -35,10 +39,9 @@ const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => {
},
})}
onClick={() => {
if (item.type == "menu") {
dispatch({type: "COLLAPSE_MENU", key: item.key});
if (hasSubItems) {
dispatch({ type: "COLLAPSE_MENU", key: item.key });
}
handleDrawerToggle();
}}
sx={{
minHeight: 48,
@@ -66,9 +69,7 @@ const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => {
}
/>
{item.type == "menu" &&
(item.showSubItem ? <ExpandLess/> : <ExpandMore/>)}
{hasSubItems && (item.showSubItem ? <ExpandLess /> : <ExpandMore />)}
</ListItemButton>
</ListItem>
{item.subItem && (

View File

@@ -15,25 +15,27 @@ import useNotification from "@/lib/app/hooks/useNotification";
const SidebarListSubItem = ({item, handleDrawerToggle}) => {
const t = useTranslations();
const {notification_count} = useNotification()
const {notification_count} = useNotification();
const renderBadge = (subitem) => (
<IconButton>
<Badge
badgeContent={notification_count ? notification_count[subitem.name] : 0}
color="error"
variant="standard"
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
/>
</IconButton>
);
return (
<Collapse in={item.showSubItem} timeout="auto" mountOnEnter={true} unmountOnExit={true}>
<List component="div" disablePadding sx={{bgcolor: "#f6f6f6", pr: 1}}>
{item.subItem.map((subitem, index) => (
<ListItem key={subitem.key} disablePadding secondaryAction={
<IconButton>
<Badge
badgeContent={notification_count ? notification_count[subitem.name] : 0}
color="error"
variant="standard"
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
/>
</IconButton>
}>
{item.subItem.map((subitem) => (
<ListItem key={subitem.key} disablePadding secondaryAction={renderBadge(subitem)}>
<ListItemButton
selected={subitem.selected}
component={NextLinkComposed}

View File

@@ -0,0 +1,23 @@
import {render, screen, waitFor} from "@testing-library/react";
import MockAppWithProviders from "../../../../../../mocks/AppWithProvider";
import SidebarDrawer from "@/components/layouts/Dashboard/Sidebar/SidebarDrawer";
describe('SidebarDrawer', () => {
describe('Rendering', () => {
it('renders system name in sidebar', async () => {
render(<MockAppWithProviders><SidebarDrawer/></MockAppWithProviders>);
await waitFor(()=>{
const systemName = screen.getByRole('heading', { level: 6 });
expect(systemName).toHaveTextContent('سامانه CRM');
})
});
it('renders user full name and position in sidebar', async () => {
localStorage.setItem("_token", 'token');
render(<MockAppWithProviders><SidebarDrawer/></MockAppWithProviders>);
await waitFor(()=>{
const userName = screen.queryByText(/Witel Company | Software Engineer/i);
expect(userName).toBeInTheDocument();
})
});
})
})

View File

@@ -0,0 +1,16 @@
import {render, screen, waitFor} from "@testing-library/react";
import MockAppWithProviders from "../../../../../../mocks/AppWithProvider";
import SidebarList from "@/components/layouts/Dashboard/Sidebar/SidebarList";
describe('SidebarList', () => {
describe('Rendering', () => {
it('renders sidebar items based on user permissions', async () => {
localStorage.setItem("_token", 'token');
render(<MockAppWithProviders><SidebarList/></MockAppWithProviders>);
await waitFor(()=>{
const sidebarItem = screen.getByText('مدیریت نقش ها');
expect(sidebarItem).toBeInTheDocument();
})
});
})
})

View File

@@ -0,0 +1,125 @@
import AccessibilityIcon from "@mui/icons-material/Accessibility";
import {fireEvent, render, screen} from "@testing-library/react";
import SidebarListItem from "@/components/layouts/Dashboard/Sidebar/SidebarListItem";
import MockAppWithProviders from "../../../../../../mocks/AppWithProvider";
describe('SidebarListItemComponent', () => {
describe('Rendering', () => {
it('should show sidebarlistitem name in sidebar', () => {
const sampleItem={
key: "sidebar.role-management",
name : "role_management",
type: "page",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: false,
permission: "manage_roles",
}
render(<MockAppWithProviders><SidebarListItem item={sampleItem} /></MockAppWithProviders>);
expect(screen.getByText('مدیریت نقش ها')).toBeInTheDocument();
});
it('should show sidebarlistitem icon in sidebar', () => {
const sampleItem={
key: "sidebar.role-management",
name : "role_management",
type: "page",
route: "/dashboard/role-management",
icon: <AccessibilityIcon aria-label="Sidebar Icon"/>,
selected: false,
permission: "manage_roles",
}
render(<MockAppWithProviders><SidebarListItem item={sampleItem} /></MockAppWithProviders>);
const iconElement = screen.getByLabelText("Sidebar Icon");
expect(iconElement).toBeInTheDocument();
});
it('should have selected class for subitem', () => {
const sampleItem={
key: "sidebar.role-management",
name : "role_management",
type: "page",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: true,
permission: "manage_roles",
}
render(<MockAppWithProviders><SidebarListItem item={sampleItem} /></MockAppWithProviders>);
const element = screen.getByText('مدیریت نقش ها');
expect(element.parentElement.parentElement).toHaveClass('Mui-selected');
});
it('should not have selected class for subitem', () => {
const sampleItem={
key: "sidebar.role-management",
name : "role_management",
type: "menu",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: false,
permission: "manage_roles",
}
render(<MockAppWithProviders><SidebarListItem item={sampleItem} /></MockAppWithProviders>);
const element = screen.getByText('مدیریت نقش ها');
expect(element.parentElement.parentElement).not.toHaveClass('Mui-selected');
});
it('should show sidebarlistitem secondary in sidebar', () => {
const sampleItem={
key: "sidebar.role-management",
name : "role_management",
secondary: "between",
type: "menu",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: false,
permission: "manage_roles",
}
render(<MockAppWithProviders><SidebarListItem item={sampleItem} /></MockAppWithProviders>);
expect(screen.getByText('میان')).toBeInTheDocument();
});
it('should not show sidebarlistitem secondary in sidebar', () => {
const sampleItem={
key: "sidebar.role-management",
name : "role_management",
type: "menu",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: false,
permission: "manage_roles",
}
render(<MockAppWithProviders><SidebarListItem item={sampleItem} /></MockAppWithProviders>);
expect(screen.queryByText('secondry')).not.toBeInTheDocument();
});
})
describe('Behavior', () => {
it('should call dispatch when hasSubItems is true and item is clicked', () => {
const dispatchMock = jest.fn();
const sampleItem={
key: "sidebar.role-management",
name : "role_management",
type: "menu",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: false,
permission: "manage_roles",
subItem :[
{
key: "greaterThan",
route: "/dashboard/role-management",
secondary: "between",
name : "sidebar.admin",
selected: true,
icon: <AccessibilityIcon />,
}
]
}
render(<MockAppWithProviders><SidebarListItem item={sampleItem} dispatch={dispatchMock}/></MockAppWithProviders>);
const listItem = screen.getByText('مدیریت نقش ها');
fireEvent.click(listItem);
expect(dispatchMock).toHaveBeenCalledWith({
type: 'COLLAPSE_MENU',
key: "sidebar.role-management",
});
});
})
})

View File

@@ -0,0 +1,103 @@
import {render, screen} from "@testing-library/react";
import MockAppWithProviders from "../../../../../../mocks/AppWithProvider";
import SidebarListSubItem from "@/components/layouts/Dashboard/Sidebar/SidebarListSubItem";
import AccessibilityIcon from "@mui/icons-material/Accessibility";
describe('SidebarListSubItemComponent', () => {
describe('Rendering', () => {
const sampleItem={
showSubItem:true,
key: "sidebar.role-management",
name : "role_management",
type: "menu",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: false,
permission: "manage_roles",
subItem :[
{
key: "greaterThan",
route: "/dashboard/role-management",
secondary: "between",
name : "sidebar.admin",
selected: true,
icon: <AccessibilityIcon aria-label="Sidebar Icon"/>,
}
]
}
it('should show subitem name in sidebar', () => {
render(<MockAppWithProviders><SidebarListSubItem item={sampleItem} /></MockAppWithProviders>);
expect(screen.getByText('بزرگتر از')).toBeInTheDocument();
});
it('should not show subitem name in sidebar', () => {
const sampleItem={
showSubItem:false,
key: "sidebar.role-management",
name : "role_management",
type: "menu",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: false,
permission: "manage_roles",
subItem :[
{
key: "greaterThan",
route: "/dashboard/role-management",
secondary: "between",
name : "sidebar.admin",
selected: false,
icon: <AccessibilityIcon />,
}
]
}
render(<MockAppWithProviders><SidebarListSubItem item={sampleItem} /></MockAppWithProviders>);
expect(screen.queryByText('مدیریت نقش ها')).not.toBeInTheDocument();
});
it('should show subitem secondary in sidebar', () => {
render(<MockAppWithProviders><SidebarListSubItem item={sampleItem} /></MockAppWithProviders>);
expect(screen.getByText('میان')).toBeInTheDocument();
});
it('should not show subitem secondary in sidebar', () => {
render(<MockAppWithProviders><SidebarListSubItem item={sampleItem} /></MockAppWithProviders>);
expect(screen.queryByText('secondry')).not.toBeInTheDocument();
});
it('should have selected class for subitem', () => {
render(<MockAppWithProviders><SidebarListSubItem item={sampleItem} /></MockAppWithProviders>);
const parentElement = screen.queryByText('بزرگتر از').parentElement.parentElement;
expect(parentElement).toHaveClass('Mui-selected');
});
it('should not have selected class for subitem', () => {
const sampleItem={
showSubItem:true,
key: "sidebar.role-management",
name : "role_management",
type: "menu",
route: "/dashboard/role-management",
icon: <AccessibilityIcon />,
selected: false,
permission: "manage_roles",
subItem :[
{
key: "greaterThan",
route: "/dashboard/role-management",
secondary: "between",
name : "sidebar.admin",
selected: false,
icon: <AccessibilityIcon />,
}
]
}
render(<MockAppWithProviders><SidebarListSubItem item={sampleItem} /></MockAppWithProviders>);
const parentElement = screen.queryByText('بزرگتر از').parentElement.parentElement;
expect(parentElement).not.toHaveClass('Mui-selected');
});
it('should show subitem icon', () => {
render(<MockAppWithProviders><SidebarListSubItem item={sampleItem} /></MockAppWithProviders>);
const iconElement = screen.getByLabelText("Sidebar Icon");
expect(iconElement).toBeInTheDocument();
});
})
})

View File

@@ -0,0 +1,17 @@
import {render, screen, act} from "@testing-library/react";
import MockAppWithProviders from "../../../../../../mocks/AppWithProvider";
import Sidebar from "@/components/layouts/Dashboard/Sidebar";
describe('Sidebar', () => {
describe('Rendering', () => {
it('Mobile Drawer is displayed when mobileOpen is true', () => {
const props={
mobileOpen: true,
};
render(<MockAppWithProviders><Sidebar {...props}/></MockAppWithProviders>);
const mobileDrawer = screen.getByTestId('mobile-drawer');
expect(mobileDrawer).toBeVisible();
});
})
})

View File

@@ -9,6 +9,7 @@ const Sidebar = (props) => {
aria-label="mailbox folders"
>
<Drawer
data-testid="mobile-drawer"
container={props.container}
variant="temporary"
open={props.mobileOpen}