From dd2ffa8a3c4fbca20a4210a805b6949a8ef59ed5 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 30 Sep 2023 16:44:54 +0330 Subject: [PATCH 01/20] CFE-3 making directories and making test file for expert management and write first test --- .../DataTable/__tests__/index.test.js | 39 +++++++++++++++++++ .../expert-management/DataTable/index.jsx | 7 ++++ .../expert-management/TableRowActions.jsx | 0 .../expert-management/TableToolbar.jsx | 0 .../dashboard/expert-management/index.jsx | 12 ++++++ .../dashboard/expert-management/index.jsx | 23 +++++++++++ 6 files changed, 81 insertions(+) create mode 100644 src/components/dashboard/expert-management/DataTable/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/DataTable/index.jsx create mode 100644 src/components/dashboard/expert-management/TableRowActions.jsx create mode 100644 src/components/dashboard/expert-management/TableToolbar.jsx create mode 100644 src/components/dashboard/expert-management/index.jsx create mode 100644 src/pages/dashboard/expert-management/index.jsx diff --git a/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js b/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js new file mode 100644 index 0000000..4d8b676 --- /dev/null +++ b/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js @@ -0,0 +1,39 @@ +import {render, screen} from "@testing-library/react"; +import MockAppWithProviders from "../../../../../../mocks/AppWithProvider"; +import ExpertManagementDataTable from "@/components/dashboard/expert-management/DataTable"; + +describe("Expert Management Component From Expert Management", () => { + describe("Rendering", () => { + it("Table Headers Rendered", () => { + render(); + const idHeader = screen.queryByText(/کد یکتا/i); + const nameHeader = screen.queryByText(/نام/i); + const usernameHeader = screen.queryByText(/نام کاربری/i); + const emailHeader = screen.queryByText(/پست الکترونیک/i); + const phone_numberHeader = screen.queryByText(/شماره همراه/i); + const national_idHeader = screen.queryByText(/کد ملی/i); + const positionHeader = screen.queryByText(/سمت/i); + const province_nameHeader = screen.queryByText(/استان/i); + const city_nameHeader = screen.queryByText(/شهر/i); + const role_nameHeader = screen.queryByText(/نقش/i); + const updated_atHeader = screen.queryByText(/آخرین بروزرسانی/i); + expect(idHeader).toBeInTheDocument(); + expect(nameHeader).toBeInTheDocument(); + expect(usernameHeader).toBeInTheDocument(); + expect(emailHeader).toBeInTheDocument(); + expect(phone_numberHeader).toBeInTheDocument(); + expect(national_idHeader).toBeInTheDocument(); + expect(positionHeader).toBeInTheDocument(); + expect(province_nameHeader).toBeInTheDocument(); + expect(city_nameHeader).toBeInTheDocument(); + expect(role_nameHeader).toBeInTheDocument(); + expect(updated_atHeader).toBeInTheDocument(); + }); + }); + describe("Behavioral", () => { + + }); + describe("Validation", () => { + + }); +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/DataTable/index.jsx b/src/components/dashboard/expert-management/DataTable/index.jsx new file mode 100644 index 0000000..9dee9b6 --- /dev/null +++ b/src/components/dashboard/expert-management/DataTable/index.jsx @@ -0,0 +1,7 @@ +function ExpertManagementDataTable() { + return ( +

asdads

+ ); +} + +export default ExpertManagementDataTable; \ No newline at end of file diff --git a/src/components/dashboard/expert-management/TableRowActions.jsx b/src/components/dashboard/expert-management/TableRowActions.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/TableToolbar.jsx b/src/components/dashboard/expert-management/TableToolbar.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/index.jsx b/src/components/dashboard/expert-management/index.jsx new file mode 100644 index 0000000..0b3f5ef --- /dev/null +++ b/src/components/dashboard/expert-management/index.jsx @@ -0,0 +1,12 @@ +import DashboardLayouts from "@/layouts/dashboardLayouts"; +import ExpertManagementDataTable from "@/components/dashboard/expert-management/DataTable"; + +function DashboardExpertManagementComponent() { + return ( + + + + ); +} + +export default DashboardExpertManagementComponent; diff --git a/src/pages/dashboard/expert-management/index.jsx b/src/pages/dashboard/expert-management/index.jsx new file mode 100644 index 0000000..60dc6e2 --- /dev/null +++ b/src/pages/dashboard/expert-management/index.jsx @@ -0,0 +1,23 @@ +import WithAuthMiddleware from "@/middlewares/WithAuth"; +import {parse} from "next-useragent"; +import DashboardExpertManagementComponent from "@/components/dashboard/expert-management"; + +export default function ExpertManagement() { + return ( + + + + ); +} + +export async function getServerSideProps({req, locale}) { + const {isBot} = parse(req.headers["user-agent"]); + return { + props: { + messages: (await import(`&/locales/${locale}/app.json`)).default, + title: "Dashboard.expert_management", + isBot, + locale + }, + }; +} From 53c03fb418a7168a64fce9d231e8ff8340d99f01 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 2 Oct 2023 16:25:29 +0330 Subject: [PATCH 02/20] CFE-3 bringing all directories and finish test of DataTable index and start CreatForm test --- public/locales/fa/app.json | 14 ++ .../DataTable/__tests__/index.test.js | 30 ++- .../expert-management/DataTable/index.jsx | 182 +++++++++++++++++- .../Form/ChangePassword/index.jsx | 7 + .../CreateContent/__tests__/index.test.js | 0 .../Form/CreateForm/CreateContent/index.jsx | 0 .../Form/CreateForm/__tests__/index.test.js | 18 ++ .../Form/CreateForm/index.jsx | 30 +++ .../Form/DeleteForm/index.jsx | 7 + .../Form/UpdateForm/index.jsx | 7 + .../expert-management/TableRowActions.jsx | 28 +++ .../expert-management/TableToolbar.jsx | 14 ++ src/core/components/DataTable.jsx | 10 +- src/core/data/apiRoutes.js | 6 +- src/lib/app/contexts/language.jsx | 6 +- 15 files changed, 328 insertions(+), 31 deletions(-) create mode 100644 src/components/dashboard/expert-management/Form/ChangePassword/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/DeleteForm/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/index.jsx diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index e813849..734325b 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -118,5 +118,19 @@ "upload_file_format": "فرمت قابل قبول : png,jpg,pdf", "delete": "پاک کردن", "uploadfile_error": "حجم فایل بیشتر از 2 مگابایت می باشد" + }, + "ExpertMangement": { + "id": "کد یکتا", + "name": "نام", + "username": "نام کاربری", + "email": "پست الکترونیک", + "phone_number": "شماره همراه", + "national_id": "کد ملی", + "position": "سمت", + "province_name": "استان", + "city_name": "شهر", + "role_name": "نقش", + "updated_at": "آخرین بروزرسانی", + "create": "افزودن کارشناس" } } diff --git a/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js b/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js index 4d8b676..3b7f516 100644 --- a/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js @@ -2,21 +2,21 @@ import {render, screen} from "@testing-library/react"; import MockAppWithProviders from "../../../../../../mocks/AppWithProvider"; import ExpertManagementDataTable from "@/components/dashboard/expert-management/DataTable"; -describe("Expert Management Component From Expert Management", () => { +describe("ExpertManagementDatatable Component From Expert Management", () => { describe("Rendering", () => { it("Table Headers Rendered", () => { render(); - const idHeader = screen.queryByText(/کد یکتا/i); - const nameHeader = screen.queryByText(/نام/i); - const usernameHeader = screen.queryByText(/نام کاربری/i); - const emailHeader = screen.queryByText(/پست الکترونیک/i); - const phone_numberHeader = screen.queryByText(/شماره همراه/i); - const national_idHeader = screen.queryByText(/کد ملی/i); - const positionHeader = screen.queryByText(/سمت/i); - const province_nameHeader = screen.queryByText(/استان/i); - const city_nameHeader = screen.queryByText(/شهر/i); - const role_nameHeader = screen.queryByText(/نقش/i); - const updated_atHeader = screen.queryByText(/آخرین بروزرسانی/i); + const idHeader = screen.queryByText("کد یکتا"); + const nameHeader = screen.queryByText("نام"); + const usernameHeader = screen.queryByText("نام کاربری"); + const emailHeader = screen.queryByText("پست الکترونیک"); + const phone_numberHeader = screen.queryByText("شماره همراه"); + const national_idHeader = screen.queryByText("کد ملی"); + const positionHeader = screen.queryByText("سمت"); + const province_nameHeader = screen.queryByText("استان"); + const city_nameHeader = screen.queryByText("شهر"); + const role_nameHeader = screen.queryByText("نقش"); + const updated_atHeader = screen.queryByText("آخرین بروزرسانی"); expect(idHeader).toBeInTheDocument(); expect(nameHeader).toBeInTheDocument(); expect(usernameHeader).toBeInTheDocument(); @@ -30,10 +30,4 @@ describe("Expert Management Component From Expert Management", () => { expect(updated_atHeader).toBeInTheDocument(); }); }); - describe("Behavioral", () => { - - }); - describe("Validation", () => { - - }); }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/DataTable/index.jsx b/src/components/dashboard/expert-management/DataTable/index.jsx index 9dee9b6..67bb64f 100644 --- a/src/components/dashboard/expert-management/DataTable/index.jsx +++ b/src/components/dashboard/expert-management/DataTable/index.jsx @@ -1,6 +1,186 @@ +import DataTable from "@/core/components/DataTable"; +import MuiDatePicker from "@/core/components/MuiDatePicker"; +import {GET_EXPERT_MANAGEMENT_LIST} from "@/core/data/apiRoutes"; +import TableToolbar from "../TableToolbar"; +import TableRowActions from "../TableRowActions"; +import {Box, Typography} from "@mui/material"; +import {useTranslations} from "next-intl"; +import {useMemo} from "react"; + function ExpertManagementDataTable() { + const t = useTranslations(); + const columns = useMemo( + () => [ + { + accessorFn: (row) => row.id, + id: "id", + header: t("ExpertMangement.id"), + enableColumnFilter: true, + datatype: "numeric", + filterFn: "equals", + columnFilterModeOptions: [ + "equals", + "notEquals", + "contains", + "lessThan", + "greaterThan", + "between", + ], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.name, + id: "name", + header: t("ExpertMangement.name"), + enableColumnFilter: true, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.username, + id: "username", + header: t("ExpertMangement.username"), + enableColumnFilter: true, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.email, + id: "email", + header: t("ExpertMangement.email"), + enableColumnFilter: true, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.phone_number, + id: "phone_number", + header: t("ExpertMangement.phone_number"), + enableColumnFilter: true, + datatype: "numeric", + filterFn: "equals", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.national_id, + id: "national_id", + header: t("ExpertMangement.national_id"), + enableColumnFilter: true, + datatype: "numeric", + filterFn: "equals", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.position, + id: "position", + header: t("ExpertMangement.position"), + enableColumnFilter: true, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.province_name, + id: "province_name", + header: t("ExpertMangement.province_name"), + enableColumnFilter: false, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.city_name, + id: "city_name", + header: t("ExpertMangement.city_name"), + enableColumnFilter: false, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => row.roles[0].name_fa, + id: "roles[0].name_fa", + header: t("ExpertMangement.role_name"), + enableColumnFilter: false, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue} + ), + }, + { + accessorFn: (row) => + moment(row.updated_at).locale("fa").format("HH:mm | yyyy/MM/DD"), + id: "updated_at", + header: t("ExpertMangement.updated_at"), + enableColumnFilter: true, + datatype: "date", + filterFn: "lessThan", + columnFilterModeOptions: ["lessThan", "greaterThan"], + Cell: ({renderedCellValue}) => { + return {renderedCellValue}; + }, + Header: ({column}) => <>{column.columnDef.header}, + Filter: ({column}) => { + return ( + + ); + }, + }, + ], + [] + ); return ( -

asdads

+ + + ); } diff --git a/src/components/dashboard/expert-management/Form/ChangePassword/index.jsx b/src/components/dashboard/expert-management/Form/ChangePassword/index.jsx new file mode 100644 index 0000000..ea3d11c --- /dev/null +++ b/src/components/dashboard/expert-management/Form/ChangePassword/index.jsx @@ -0,0 +1,7 @@ +const ChangePassword = () => { + return ( + <> + ) +} + +export default ChangePassword \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js new file mode 100644 index 0000000..20feced --- /dev/null +++ b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js @@ -0,0 +1,18 @@ +import {render, screen} from "@testing-library/react"; +import MockAppWithProviders from "../../../../../../mocks/AppWithProvider"; +import CreateForm from "../../CreateForm"; + +describe("CreateForm Component From Expert Management", () => { + describe("Rendering", () => { + it("Create Button Rendered", () => { + render(); + const versionControler = screen.queryByTitle("ثبت کارشناس"); + expect(versionControler).toBeInTheDocument(); + }); + it("Dialog Header Rendered", () => { + render(); + const versionControler = screen.queryByText("ثبت کارشناس"); + expect(versionControler).toBeInTheDocument(); + }); + }); +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/index.jsx new file mode 100644 index 0000000..09c6a5b --- /dev/null +++ b/src/components/dashboard/expert-management/Form/CreateForm/index.jsx @@ -0,0 +1,30 @@ +const Create = () => { + return ( + <> + + + + + + + {t("ExpertMangement.create")} + + + + ) +} + +export default Create \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx b/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx new file mode 100644 index 0000000..11320cc --- /dev/null +++ b/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx @@ -0,0 +1,7 @@ +const Delete = () => { + return ( + <> + ) +} + +export default Delete \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/index.jsx new file mode 100644 index 0000000..59da7cd --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/index.jsx @@ -0,0 +1,7 @@ +const Update = () => { + return ( + <> + ) +} + +export default Update \ No newline at end of file diff --git a/src/components/dashboard/expert-management/TableRowActions.jsx b/src/components/dashboard/expert-management/TableRowActions.jsx index e69de29..19830ce 100644 --- a/src/components/dashboard/expert-management/TableRowActions.jsx +++ b/src/components/dashboard/expert-management/TableRowActions.jsx @@ -0,0 +1,28 @@ +import {Box} from "@mui/material"; +import Update from "./Form/UpdateForm" +import Delete from "./Form/DeleteForm"; +import ChangePassword from "./Form/ChangePassword"; + +const TableRowActions = ({row, mutate, fetchUrl}) => { + return ( + + + + + + ); +}; + +export default TableRowActions; diff --git a/src/components/dashboard/expert-management/TableToolbar.jsx b/src/components/dashboard/expert-management/TableToolbar.jsx index e69de29..7eb047b 100644 --- a/src/components/dashboard/expert-management/TableToolbar.jsx +++ b/src/components/dashboard/expert-management/TableToolbar.jsx @@ -0,0 +1,14 @@ +import {useTranslations} from "next-intl"; +import Create from "./Form/CreateForm"; +import {Box} from "@mui/material"; + +function TableToolbar({mutate, fetchUrl}) { + const t = useTranslations(); + return ( + + + + ); +} + +export default TableToolbar; diff --git a/src/core/components/DataTable.jsx b/src/core/components/DataTable.jsx index b3b0f26..10fdffa 100644 --- a/src/core/components/DataTable.jsx +++ b/src/core/components/DataTable.jsx @@ -42,13 +42,11 @@ function DataTable(props) { const [updateTime, setupdateTime] = useState( moment().format("HH:mm | jYYYY/jM/jD") ); - const tableLocalization = useMemo( () => languageList.find((item) => item.key == languageApp).tableLocalization, [languageApp, languageList] ); - const fetchUrl = useMemo(() => { const url = new URL(props.tableUrl); url.searchParams.set( @@ -73,12 +71,10 @@ function DataTable(props) { url.searchParams.set("sorting", JSON.stringify(sorting ?? [])); return url; }, [ - props.tableUrl, columnFilters, columnFilterFns, pagination, sorting, - props.columns, ]); const {data, isValidating, mutate} = useSWR(fetchUrl, fetcher, { @@ -91,6 +87,7 @@ function DataTable(props) { setupdateTime(moment().format("HH:mm | jYYYY/jM/jD")); }, [isValidating, languageApp]); + return ( ( <> {props.enableCustomToolbar /* send condition */ - ? props.CustomToolbar /* send component */ - : ""} + ? () /* send component */ + : } )} renderBottomToolbarCustomActions={({table}) => ( @@ -159,7 +156,6 @@ function DataTable(props) { )} state={{ - isLoading: isValidating, columnFilters, columnFilterFns, pagination, diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index 06dd4e9..e9351ad 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -10,4 +10,8 @@ export const SET_USER_PASSWORD = BASE_URL + "/dashboard/profile/change_password" //user data export const GET_USER_ROUTE = BASE_URL + "/dashboard/profile/info"; -//user data \ No newline at end of file +//user data + +//expert management +export const GET_EXPERT_MANAGEMENT_LIST = BASE_URL + "/dashboard/experts/show"; +//expert management \ No newline at end of file diff --git a/src/lib/app/contexts/language.jsx b/src/lib/app/contexts/language.jsx index e3f41f4..e9e24f7 100644 --- a/src/lib/app/contexts/language.jsx +++ b/src/lib/app/contexts/language.jsx @@ -18,7 +18,7 @@ export const LanguageProvider = ({children}) => { ]; const {user, userChangedLanguage, changeLanguageState} = useUser(); const [languageIsReady, setLanguageIsReady] = useState(false); - const [languageApp, setLanguageApp] = useState(); + const [languageApp, setLanguageApp] = useState(process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE); const [directionApp, setDirectionApp] = useState( process.env.NEXT_PUBLIC_DEFAULT_DIRECTION ); @@ -26,9 +26,7 @@ export const LanguageProvider = ({children}) => { useEffect(() => { const lang = localStorage.getItem("_language"); - if (!lang && !languageApp) { - setLanguageApp(process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE); - } else if (lang) { + if (lang) { setLanguageApp(lang); } }, []); From 583d4aa3323fbbb9b4dd3048fcd0c316c8799a97 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Wed, 4 Oct 2023 14:19:42 +0330 Subject: [PATCH 03/20] CFE-3 complete behavioral and rendering tests for CreateForm Component and start CreateContent testing component --- public/locales/fa/app.json | 6 ++++-- .../CreateContent/__tests__/index.test.js | 0 .../Form/CreateForm/__tests__/index.test.js | 15 +++++++-------- .../dashboard/expert-management/index.jsx | 2 +- src/core/data/sidebarMenu.jsx | 12 +++++++++++- 5 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 734325b..06b811d 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -32,7 +32,8 @@ "dashboard": "داشبورد", "change-password": "تغییر رمز عبور", "edit-profile": "ویرایش پروفایل", - "admin": "مدیریت" + "admin": "مدیریت", + "expert-management": "مدیریت کارشناسان" }, "secondary": { }, @@ -70,7 +71,8 @@ "Dashboard": { "dashboard_page": "داشبورد", "change_password": "تغییر رمز عبور", - "edit_profile": "ویرایش پروفایل" + "edit_profile": "ویرایش پروفایل", + "expert_management": "داشبورد" }, "MuiDatePicker": { "date_picker_birthday": "تاریخ" diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js index d036cee..1e85160 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js @@ -1,10 +1,8 @@ -import {fireEvent, render, screen} from "@testing-library/react"; -import React, {useState} from 'react'; +import {act, fireEvent, render, screen} from "@testing-library/react"; +import React from 'react'; import MockAppWithProviders from "../../../../../../../mocks/AppWithProvider"; import CreateForm from "../../CreateForm"; -jest.spyOn(React, 'useState'); - describe("CreateForm Component From Expert Management", () => { describe("Rendering", () => { it("Create Button Rendered", () => { @@ -19,13 +17,14 @@ describe("CreateForm Component From Expert Management", () => { }); }); describe("Behavioral", () => { - it("by Clicking Create Button Dialog State Should Change (true/false)", () => { - const setOpenCreateDialogMock = jest.fn(); - useState.mockReturnValue([false, setOpenCreateDialogMock]); + it("by Clicking Create Button Dialog Should Append To Document", async () => { render(); const CreateButton = screen.getByRole('button', {name: "افزودن کارشناس"}); fireEvent.click(CreateButton); - expect(setOpenCreateDialogMock).toHaveBeenCalledWith(true); + await act(() => { + const CreateDialog = screen.getByRole('dialog', {name: "افزودن کارشناس"}) + expect(CreateDialog).toBeInTheDocument(); + }); }); }); }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/index.jsx b/src/components/dashboard/expert-management/index.jsx index 0b3f5ef..632d89b 100644 --- a/src/components/dashboard/expert-management/index.jsx +++ b/src/components/dashboard/expert-management/index.jsx @@ -1,4 +1,4 @@ -import DashboardLayouts from "@/layouts/dashboardLayouts"; +import DashboardLayouts from "@/layouts/DashboardLayout"; import ExpertManagementDataTable from "@/components/dashboard/expert-management/DataTable"; function DashboardExpertManagementComponent() { diff --git a/src/core/data/sidebarMenu.jsx b/src/core/data/sidebarMenu.jsx index ca946a5..d1434a1 100644 --- a/src/core/data/sidebarMenu.jsx +++ b/src/core/data/sidebarMenu.jsx @@ -1,4 +1,5 @@ import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard"; +import ManageAccountsIcon from '@mui/icons-material/ManageAccounts'; const sidebarMenu = [ [ @@ -6,7 +7,16 @@ const sidebarMenu = [ key: "sidebar.dashboard", type: "page", route: "/dashboard", - icon: , + icon: , + selected: false, + permission: "all", + }, + { + key: "sidebar.expert-management", + type: "page", + name: "expert_management", + route: "/dashboard/expert-management", + icon: , selected: false, permission: "all", }, From ab568e0b28051554343cd25d2c222ed72204e529 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 7 Oct 2023 15:14:30 +0330 Subject: [PATCH 04/20] CFE-3 add handler (write a mock) for provinceList and RoleList and add their hooks and write rendering test for CreateContent component --- mocks/handler.js | 48 ++- public/locales/fa/app.json | 36 +- .../CreateContent/__tests__/index.test.js | 83 ++++ .../Form/CreateForm/CreateContent/index.jsx | 374 +++++++++++++++++- src/core/data/apiRoutes.js | 10 + src/lib/app/hooks/useProvince.jsx | 29 ++ src/lib/app/hooks/useRole.jsx | 29 ++ 7 files changed, 598 insertions(+), 11 deletions(-) create mode 100644 src/lib/app/hooks/useProvince.jsx create mode 100644 src/lib/app/hooks/useRole.jsx diff --git a/mocks/handler.js b/mocks/handler.js index 3a8f75d..45183f9 100644 --- a/mocks/handler.js +++ b/mocks/handler.js @@ -1,10 +1,42 @@ -import {GET_USER_ROUTE} from "@/core/data/apiRoutes"; +import {GET_PROVINCE_LIST, GET_ROLE_LIST, GET_USER_ROUTE} from "@/core/data/apiRoutes"; import {rest} from "msw"; -export const handler = [rest.get(GET_USER_ROUTE, (req, res, ctx) => { - return res(ctx.json({ - data: { - id: 10 - } - })) -})] \ No newline at end of file +export const handler = [ + rest.get(GET_USER_ROUTE, (req, res, ctx) => { + return res(ctx.json({ + data: { + id: 10 + } + })) + }), + rest.get(GET_PROVINCE_LIST, (req, res, ctx) => { + return res(ctx.json({ + data: [ + { + id: 1, + name: "آذربایجان شرقی" + }, + { + id: 3, + name: "اردبیل" + } + ] + })) + }), + rest.get(GET_ROLE_LIST, (req, res, ctx) => { + return res(ctx.json({ + data: [ + { + id: 1, + name: "passenger_office_chief", + name_fa: "رئیس اداره مسافری استان" + }, + { + id: 4, + name: "province_manager", + name_fa: "مدیر کل استانی" + } + ] + })) + }) +] \ No newline at end of file diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 06b811d..4f7eef8 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -133,6 +133,40 @@ "city_name": "شهر", "role_name": "نقش", "updated_at": "آخرین بروزرسانی", - "create": "افزودن کارشناس" + "create": "افزودن کارشناس", + "personal_info": "مشخصات کارشناس", + "user_info": "اطلاعات کاربری", + "rest_info": "اطلاعات تکمیلی", + "text_field_name": "نام", + "text_field_username": "نام کاربری", + "text_field_email": "پست الکترونیک", + "text_field_phone_number": "شماره همراه", + "text_field_national_id": "کد ملی", + "text_field_password": "رمز عبور", + "text_field_position": "سمت", + "text_field_province_id": "استان", + "text_field_city_id": "شهر", + "text_field_role_id": "نقش", + "text_field_loading_provinces_list": "درحال دریافت شهر ها", + "text_field_error_fetching_provinces": "خطا در دریافت شهر ها", + "text_field_loading_roles_list": "درحال دریافت نقش ها", + "text_field_error_fetching_roles": "خطا در دریافت نقش ها", + "text_field_please_select_province": "ابتدا استان خود را انتخاب کنید", + "text_field_loading_cities_list": "درحال دریافت شهر ها", + "text_field_error_fetching_cities": "خطا در دریافت شهر ها", + "text_field_new_password": "رمز عبور جدید", + "error_message_name": "نام خود را وارد کنید", + "error_message_username": "نام کاربری خود را وارد کنید", + "error_message_email": "پست الکترونیک خود را وارد کنید", + "error_message_phone_number": "شماره همراه خود را وارد کنید", + "error_message_national_id": "کد ملی خود را وارد کنید", + "error_message_password": "رمز عبور خود را وارد کنید", + "error_message_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد", + "error_message_position": "سمت خود را وارد کنید", + "error_message_province_id": "استان خود را وارد کنید", + "error_message_city_id": "شهر خود را وارد کنید", + "error_message_role_id": "نقش خود را وارد کنید", + "error_message_new_password": "رمز عبور جدید را وارد کنید", + "error_message_new_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد" } } diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index e69de29..cf93005 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -0,0 +1,83 @@ +import {act, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import CreateContent from "../../CreateContent"; +import MockAppWithProviders from "../../../../../../../../mocks/AppWithProvider"; + +describe("CreateContent Component From Expert Management", () => { + describe("Rendering", () => { + it("Name TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.queryByLabelText('نام'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("UserName TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.queryByLabelText('نام کاربری'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("Email TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.queryByLabelText('پست الکترونیک'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("Phone Number TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.queryByLabelText('شماره همراه'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("National Id TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.queryByLabelText('کد ملی'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("Password TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.queryByLabelText('رمز عبور'); + expect(nameTextField).toBeInTheDocument(); + }); + + }); + it("Position TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.queryByLabelText('سمت'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("Province TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.getByTestId('province-select'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("City TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.getByTestId('city-select'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("Role TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.getByTestId('role-select'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + + }); +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx index 7ce4fcf..8f24ef4 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx @@ -1,7 +1,377 @@ -const CreateContent = () => { +import { + Box, + Button, + Chip, + DialogActions, + DialogContent, + Divider, + FormControl, + FormHelperText, + Grid, + IconButton, + InputAdornment, + InputLabel, + MenuItem, + Select, + TextField, +} from "@mui/material"; +import * as Yup from "yup"; +import {useTranslations} from "next-intl"; +import {useFormik} from "formik"; +import {useState} from "react"; +import useRequest from "@/lib/app/hooks/useRequest"; +import {CREATE_EXPERT_MANAGEMENT, GET_CITY_LIST} from "@/core/data/apiRoutes"; +import useRole from "@/lib/app/hooks/useRole"; +import {Visibility, VisibilityOff} from "@mui/icons-material"; +import useProvince from "@/lib/app/hooks/useProvince"; + +const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { + const t = useTranslations(); + const requestServer = useRequest() + const [cityList, setCityList] = useState([]); + const [cityTextField, setCityTextField] = useState(t("ExpertMangement.text_field_please_select_province")); + const {provinceList, isLoadingProvinceList, errorProvinceList} = useProvince(); + const {roleList, isLoadingRoleList, errorRoleList} = useRole(); + const [showPassword, setShowPassword] = useState(false); + + const handleClickShowPassword = () => { + setShowPassword(!showPassword); + }; + + function getCities(province_id) { + formik.setFieldTouched("city_id", false, false); + formik.setFieldValue("city_id", "") + setCityTextField(t("ExpertMangement.text_field_loading_cities_list")) + requestServer(`${GET_CITY_LIST}?province_id=${province_id}`, "get", {auth: true, notification: false}) + .then(({data}) => { + const result = data.data; + const formattedData = result.map((city, index) => ({ + id: index, + name: city.name, + value: city.id, + })); + setCityList(formattedData); + setCityTextField(t("ExpertMangement.text_field_city_id")) + }).catch(() => { + setCityTextField(t("ExpertMangement.text_field_error_fetching_cities")) + }); + } + + const validationSchema = Yup.object().shape({ + name: Yup.string().required(t("ExpertMangement.error_message_name")), + username: Yup.string().required(t("ExpertMangement.error_message_username")), + email: Yup.string().required(t("ExpertMangement.error_message_email")), + phone_number: Yup.string().required(t("ExpertMangement.error_message_phone_number")), + national_id: Yup.string().required(t("ExpertMangement.error_message_national_id")), + password: Yup.string() + .required(t("ExpertMangement.error_message_password")) + .matches( + /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/, + t("ExpertMangement.error_message_password_regex") + ), + position: Yup.string().required(t("ExpertMangement.error_message_position")), + province_id: Yup.string().required(t("ExpertMangement.error_message_province_id")), + city_id: Yup.string().required(t("ExpertMangement.error_message_city_id")), + role_id: Yup.string().required(t("ExpertMangement.error_message_role_id")) + }); + + const formik = useFormik({ + initialValues: { + name: "", + username: "", + email: "", + phone_number: "", + national_id: "", + password: "", + position: "", + province_id: "", + city_id: "", + role_id: "" + }, + validationSchema, + onSubmit: (values, {setSubmitting}) => { + const formData = new FormData(); + formData.append("name", values.name); + formData.append("national_id", values.national_id); + formData.append("phone_number", values.phone_number); + formData.append("email", values.email); + formData.append("username", values.username); + formData.append("password", values.password); + formData.append("province_id", values.province_id); + formData.append("city_id", values.city_id); + formData.append("position", values.position); + formData.append("role_id", values.role_id); + + requestServer(`${CREATE_EXPERT_MANAGEMENT}`, 'post', {auth: true, data: formData}) + .then((response) => { + mutate(fetchUrl) + setOpenCreateDialog(false) + }).catch(() => { + }).finally(() => { + setSubmitting(false); + }); + }, + }); + return ( <> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {showPassword ? : } + + + ), + }} + sx={{width: "100%"}} + /> + + + + + + + + + + + {t("ExpertMangement.text_field_province_id")} + + + {formik.touched.province_id && formik.errors.province_id ? formik.errors.province_id : ""} + + + + + + {cityTextField} + + + {formik.touched.city_id && formik.errors.city_id ? formik.errors.city_id : ""} + + + + + + + + + + + {t("ExpertMangement.text_field_role_id")} + + + {formik.touched.role_id && formik.errors.role_id ? formik.errors.role_id : ""} + + + + + + + ) } diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index 543e9a4..6e604c1 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -1,5 +1,14 @@ const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL; +// role list +export const GET_ROLE_LIST = BASE_URL + "/dashboard/roles/list"; +// role list + +// province/city list +export const GET_PROVINCE_LIST = BASE_URL + "/api/provinces"; +export const GET_CITY_LIST = BASE_URL + "/api/cities"; +// province/city list + //login export const GET_USER_TOKEN = BASE_URL + "/api/auth/login"; //end login @@ -14,4 +23,5 @@ export const GET_USER_ROUTE = BASE_URL + "/api/profile/info"; //expert management export const GET_EXPERT_MANAGEMENT_LIST = BASE_URL + "/dashboard/experts/show"; +export const CREATE_EXPERT_MANAGEMENT = BASE_URL + "/dashboard/experts/store"; //expert management \ No newline at end of file diff --git a/src/lib/app/hooks/useProvince.jsx b/src/lib/app/hooks/useProvince.jsx new file mode 100644 index 0000000..359eff4 --- /dev/null +++ b/src/lib/app/hooks/useProvince.jsx @@ -0,0 +1,29 @@ +import {GET_PROVINCE_LIST} from "@/core/data/apiRoutes"; +import useRequest from "@/lib/app/hooks/useRequest"; +import useSWR from "swr"; + +const useProvince = () => { + const requestServer = useRequest({auth: true, notification: false}) + + //swr config + const fetcher = (...args) => { + return requestServer(args, 'get').then(({data}) => { + return data.data; + }).catch(() => { + }) + }; + + const {data, isLoading} = useSWR(GET_PROVINCE_LIST, fetcher, { + revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false + }); + + return { + provinceList: data, + isLoadingProvinceList: isLoading, + errorProvinceList: !data + } +}; + +export default useProvince; \ No newline at end of file diff --git a/src/lib/app/hooks/useRole.jsx b/src/lib/app/hooks/useRole.jsx new file mode 100644 index 0000000..fc3dd18 --- /dev/null +++ b/src/lib/app/hooks/useRole.jsx @@ -0,0 +1,29 @@ +import {GET_ROLE_LIST} from "@/core/data/apiRoutes"; +import useRequest from "@/lib/app/hooks/useRequest"; +import useSWR from "swr"; + +const useRole = () => { + const requestServer = useRequest({auth: true, notification: false}) + + //swr config + const fetcher = (...args) => { + return requestServer(args, 'get').then(({data}) => { + return data.data; + }).catch(() => { + }) + }; + + const {data, isLoading} = useSWR(GET_ROLE_LIST, fetcher, { + revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false + }); + + return { + roleList: data, + isLoadingRoleList: isLoading, + errorRoleList: !data + } +}; + +export default useRole; \ No newline at end of file From 783fbf28420787fefe2205a599fcc7e3ef22a675 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 7 Oct 2023 17:44:02 +0330 Subject: [PATCH 05/20] CFE-3 Fencing CreateContent component because of rendering problem that caused in testing --- .../PersonalInfo/__tests__/index.test.js | 0 .../CreateContent/PersonalInfo/index.jsx | 73 +++++++++++ .../RestInfo/__tests__/index.test.js | 0 .../CreateContent/RestInfo/index.jsx | 0 .../UserInfo/__test__/index.test.js | 0 .../CreateContent/UserInfo/index.jsx | 54 ++++++++ .../CreateContent/__tests__/index.test.js | 119 ++++++++++++++---- .../Form/CreateForm/CreateContent/index.jsx | 110 +--------------- 8 files changed, 228 insertions(+), 128 deletions(-) create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/index.jsx diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/index.jsx new file mode 100644 index 0000000..9254771 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/index.jsx @@ -0,0 +1,73 @@ +import {Grid, TextField} from "@mui/material"; +import {useTranslations} from "next-intl"; + +const PersonalInfo = ({formik}) => { + const t = useTranslations(); + return ( + <> + + + + + + + + + + + + + + + + ) +} +export default PersonalInfo \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js new file mode 100644 index 0000000..e69de29 diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/index.jsx new file mode 100644 index 0000000..189f997 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/index.jsx @@ -0,0 +1,54 @@ +import {Grid, IconButton, InputAdornment, TextField} from "@mui/material"; +import {useTranslations} from "next-intl"; +import {Visibility, VisibilityOff} from "@mui/icons-material"; + +const UserInfo = ({formik}) => { + const t = useTranslations(); + return ( + <> + + + + + + + + {showPassword ? : } + + + ), + }} + sx={{width: "100%"}} + /> + + + + ) +} +export default UserInfo \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index cf93005..fee508f 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -1,4 +1,4 @@ -import {act, render, screen, waitFor} from "@testing-library/react"; +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import CreateContent from "../../CreateContent"; import MockAppWithProviders from "../../../../../../../../mocks/AppWithProvider"; @@ -15,69 +15,142 @@ describe("CreateContent Component From Expert Management", () => { it("UserName TextField Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.queryByLabelText('نام کاربری'); - expect(nameTextField).toBeInTheDocument(); + const usernameTextField = screen.queryByLabelText('نام کاربری'); + expect(usernameTextField).toBeInTheDocument(); }); }); it("Email TextField Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.queryByLabelText('پست الکترونیک'); - expect(nameTextField).toBeInTheDocument(); + const emailTextField = screen.queryByLabelText('پست الکترونیک'); + expect(emailTextField).toBeInTheDocument(); }); }); it("Phone Number TextField Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.queryByLabelText('شماره همراه'); - expect(nameTextField).toBeInTheDocument(); + const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); + expect(phoneNumberTextField).toBeInTheDocument(); }); }); it("National Id TextField Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.queryByLabelText('کد ملی'); - expect(nameTextField).toBeInTheDocument(); + const nationalIdTextField = screen.queryByLabelText('کد ملی'); + expect(nationalIdTextField).toBeInTheDocument(); }); }); it("Password TextField Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.queryByLabelText('رمز عبور'); - expect(nameTextField).toBeInTheDocument(); + const passwordTextField = screen.queryByLabelText('رمز عبور'); + expect(passwordTextField).toBeInTheDocument(); }); }); it("Position TextField Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.queryByLabelText('سمت'); - expect(nameTextField).toBeInTheDocument(); + const positionTextField = screen.queryByLabelText('سمت'); + expect(positionTextField).toBeInTheDocument(); }); }); - it("Province TextField Rendered", async () => { + it("Province Select Box Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.getByTestId('province-select'); - expect(nameTextField).toBeInTheDocument(); + const provinceSelectBox = screen.getByTestId('province-select'); + expect(provinceSelectBox).toBeInTheDocument(); }); }); - it("City TextField Rendered", async () => { + it("City Select Box Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.getByTestId('city-select'); - expect(nameTextField).toBeInTheDocument(); + const citySelectBox = screen.getByTestId('city-select'); + expect(citySelectBox).toBeInTheDocument(); }); }); - it("Role TextField Rendered", async () => { + it("Role Select Box Rendered", async () => { render(); await waitFor(() => { - const nameTextField = screen.getByTestId('role-select'); - expect(nameTextField).toBeInTheDocument(); + const roleSelectBox = screen.getByTestId('role-select'); + expect(roleSelectBox).toBeInTheDocument(); }); }); }); describe("Behavioral", () => { - + it("Name TextField Work Correctly", async () => { + render(); + const nameTextField = screen.queryByLabelText('نام'); + fireEvent.change(nameTextField, {target: {value: 'exampleName'}}); + await act(() => { + expect(nameTextField).toHaveValue('exampleName'); + }) + }); + it("Username TextField Work Correctly", async () => { + render(); + const usernameTextField = screen.queryByLabelText('نام کاربری'); + fireEvent.change(usernameTextField, {target: {value: 'exampleUsername'}}); + await act(() => { + expect(usernameTextField).toHaveValue('exampleUsername'); + }) + }); + it("Email TextField Work Correctly", async () => { + render(); + const emailTextField = screen.queryByLabelText('پست الکترونیک'); + fireEvent.change(emailTextField, {target: {value: 'exampleEmail'}}); + await act(() => { + expect(emailTextField).toHaveValue('exampleEmail'); + }) + }); + it("Phone Number TextField Work Correctly", async () => { + render(); + const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); + fireEvent.change(phoneNumberTextField, {target: {value: 'examplePhoneNumber'}}); + await act(() => { + expect(phoneNumberTextField).toHaveValue('examplePhoneNumber'); + }) + }); + it("National Id TextField Work Correctly", async () => { + render(); + const nationalIdTextField = screen.queryByLabelText('کد ملی'); + fireEvent.change(nationalIdTextField, {target: {value: 'exampleNationalId'}}); + await act(() => { + expect(nationalIdTextField).toHaveValue('exampleNationalId'); + }) + }); + it("Password TextField Work Correctly", async () => { + render(); + const passwordTextField = screen.queryByLabelText('رمز عبور'); + fireEvent.change(passwordTextField, {target: {value: 'examplePassword'}}); + await act(() => { + expect(passwordTextField).toHaveValue('examplePassword'); + }) + }); + it("Position TextField Work Correctly", async () => { + render(); + const positionTextField = screen.queryByLabelText('سمت'); + fireEvent.change(positionTextField, {target: {value: 'examplePosition'}}); + await act(() => { + expect(positionTextField).toHaveValue('examplePosition'); + }) + }); + it("Province Select Box Work Correctly", async () => { + render(); + screen.debug() + await waitFor(() => { + expect(screen.queryByText("آذربایجان شرقی")).toBeInTheDocument(); + }, {timeout: 4000}); + // const provinceSelectBox = screen.getByTestId('province-select'); + // fireEvent.change(provinceSelectBox, {target: {value: 1}}); + // expect(provinceSelectBox).toHaveValue(1); + }); + // it("Role Select Box Work Correctly", async () => { + // render(); + // const roleSelectBox = screen.getByTestId('role-select'); + // fireEvent.change(roleSelectBox, {target: {value: '1'}}); + // await act(() => { + // expect(roleSelectBox).toHaveValue('1'); + // }) + // }); }); }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx index 8f24ef4..ae6485d 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx @@ -24,6 +24,8 @@ import {CREATE_EXPERT_MANAGEMENT, GET_CITY_LIST} from "@/core/data/apiRoutes"; import useRole from "@/lib/app/hooks/useRole"; import {Visibility, VisibilityOff} from "@mui/icons-material"; import useProvince from "@/lib/app/hooks/useProvince"; +import PersonalInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo"; +import UserInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo"; const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { const t = useTranslations(); @@ -123,68 +125,7 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { /> - - - - - - - - - - - - - - + { /> - - - - - - - - {showPassword ? : } - - - ), - }} - sx={{width: "100%"}} - /> - - + { From b3ea71862ac56d140c00e08fbb711ca08abe4bcd Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Tue, 10 Oct 2023 10:58:00 +0330 Subject: [PATCH 06/20] CFE-3 complete structure and behavior of create form of expert management --- public/locales/fa/app.json | 4 +- .../PersonalInfo/__tests__/index.test.js | 71 +++++++ .../CreateContent/PersonalInfo/index.jsx | 125 ++++++----- .../CreateContent/RestInfo/Position&Role.jsx | 69 +++++++ .../CreateContent/RestInfo/Province&City.jsx | 110 ++++++++++ .../RestInfo/__tests__/index.test.js | 65 ++++++ .../CreateContent/RestInfo/index.jsx | 12 ++ .../UserInfo/__test__/index.test.js | 42 ++++ .../CreateContent/UserInfo/index.jsx | 7 + .../CreateContent/__tests__/index.test.js | 149 +------------- .../Form/CreateForm/CreateContent/index.jsx | 194 ++---------------- src/core/data/apiRoutes.js | 8 +- 12 files changed, 466 insertions(+), 390 deletions(-) create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Position&Role.jsx create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province&City.jsx diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 4f7eef8..a7361da 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -167,6 +167,8 @@ "error_message_city_id": "شهر خود را وارد کنید", "error_message_role_id": "نقش خود را وارد کنید", "error_message_new_password": "رمز عبور جدید را وارد کنید", - "error_message_new_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد" + "error_message_new_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد", + "button_cancel": "بستن", + "button_confirm": "ثبت" } } diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js index e69de29..66aba9e 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js @@ -0,0 +1,71 @@ +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider"; +import CreateContent from "../../../CreateContent"; + +describe("PersonalInfo Component From Expert Management", () => { + describe("Rendering", () => { + it("Name TextField Rendered", async () => { + render(); + await waitFor(() => { + const nameTextField = screen.queryByLabelText('نام'); + expect(nameTextField).toBeInTheDocument(); + }); + }); + it("Email TextField Rendered", async () => { + render(); + await waitFor(() => { + const emailTextField = screen.queryByLabelText('پست الکترونیک'); + expect(emailTextField).toBeInTheDocument(); + }); + }); + it("Phone Number TextField Rendered", async () => { + render(); + await waitFor(() => { + const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); + expect(phoneNumberTextField).toBeInTheDocument(); + }); + }); + it("National Id TextField Rendered", async () => { + render(); + await waitFor(() => { + const nationalIdTextField = screen.queryByLabelText('کد ملی'); + expect(nationalIdTextField).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + it("Name TextField Work Correctly", async () => { + render(); + const nameTextField = screen.queryByLabelText('نام'); + fireEvent.change(nameTextField, {target: {value: 'exampleName'}}); + await act(() => { + expect(nameTextField).toHaveValue('exampleName'); + }) + }); + it("Email TextField Work Correctly", async () => { + render(); + const emailTextField = screen.queryByLabelText('پست الکترونیک'); + fireEvent.change(emailTextField, {target: {value: 'exampleEmail'}}); + await act(() => { + expect(emailTextField).toHaveValue('exampleEmail'); + }) + }); + it("Phone Number TextField Work Correctly", async () => { + render(); + const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); + fireEvent.change(phoneNumberTextField, {target: {value: 'examplePhoneNumber'}}); + await act(() => { + expect(phoneNumberTextField).toHaveValue('examplePhoneNumber'); + }) + }); + it("National Id TextField Work Correctly", async () => { + render(); + const nationalIdTextField = screen.queryByLabelText('کد ملی'); + fireEvent.change(nationalIdTextField, {target: {value: 'exampleNationalId'}}); + await act(() => { + expect(nationalIdTextField).toHaveValue('exampleNationalId'); + }) + }); + }); +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/index.jsx index 9254771..0dde112 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/index.jsx @@ -3,71 +3,70 @@ import {useTranslations} from "next-intl"; const PersonalInfo = ({formik}) => { const t = useTranslations(); + return ( - <> - - - - - - - - - - - - - + + + - + + + + + + + + + + ) } export default PersonalInfo \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Position&Role.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Position&Role.jsx new file mode 100644 index 0000000..47d594c --- /dev/null +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Position&Role.jsx @@ -0,0 +1,69 @@ +import {FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, TextField} from "@mui/material"; +import {useTranslations} from "next-intl"; +import useRequest from "@/lib/app/hooks/useRequest"; +import useRole from "@/lib/app/hooks/useRole"; + +const PositionAndRole = ({formik}) => { + const t = useTranslations(); + const requestServer = useRequest() + const {roleList, isLoadingRoleList, errorRoleList} = useRole(); + + return ( + + + + + + + {t("ExpertMangement.text_field_role_id")} + + + {formik.touched.role_id && formik.errors.role_id ? formik.errors.role_id : ""} + + + + + ) +} +export default PositionAndRole \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province&City.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province&City.jsx new file mode 100644 index 0000000..46245b2 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province&City.jsx @@ -0,0 +1,110 @@ +import {FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select} from "@mui/material"; +import {useTranslations} from "next-intl"; +import {useState} from "react"; +import useProvince from "@/lib/app/hooks/useProvince"; +import {GET_CITY_LIST} from "@/core/data/apiRoutes"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const ProvinceAndCity = ({formik}) => { + const t = useTranslations(); + const requestServer = useRequest() + const [cityList, setCityList] = useState([]); + const [cityTextField, setCityTextField] = useState(t("ExpertMangement.text_field_please_select_province")); + const {provinceList, isLoadingProvinceList, errorProvinceList} = useProvince(); + + function getCities(province_id) { + formik.setFieldTouched("city_id", false, false); + formik.setFieldValue("city_id", "") + setCityTextField(t("ExpertMangement.text_field_loading_cities_list")) + requestServer(`${GET_CITY_LIST}?province_id=${province_id}`, "get", {auth: true, notification: false}) + .then(({data}) => { + const result = data.data; + const formattedData = result.map((city, index) => ({ + id: index, + name: city.name, + value: city.id, + })); + setCityList(formattedData); + setCityTextField(t("ExpertMangement.text_field_city_id")) + }).catch(() => { + setCityTextField(t("ExpertMangement.text_field_error_fetching_cities")) + }); + } + + return ( + + + + {t("ExpertMangement.text_field_province_id")} + + + {formik.touched.province_id && formik.errors.province_id ? formik.errors.province_id : ""} + + + + + + {cityTextField} + + + {formik.touched.city_id && formik.errors.city_id ? formik.errors.city_id : ""} + + + + + ) +} +export default ProvinceAndCity \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js index e69de29..1139c9c 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js @@ -0,0 +1,65 @@ +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider"; +import CreateContent from "../../../CreateContent"; + +describe("CreateContent Component From Expert Management", () => { + describe("Rendering", () => { + it("Position TextField Rendered", async () => { + render(); + await waitFor(() => { + const positionTextField = screen.queryByLabelText('سمت'); + expect(positionTextField).toBeInTheDocument(); + }); + }); + it("Province Select Box Rendered", async () => { + render(); + await waitFor(() => { + const provinceSelectBox = screen.getByTestId('province-select'); + expect(provinceSelectBox).toBeInTheDocument(); + }); + }); + it("City Select Box Rendered", async () => { + render(); + await waitFor(() => { + const citySelectBox = screen.getByTestId('city-select'); + expect(citySelectBox).toBeInTheDocument(); + }); + }); + it("Role Select Box Rendered", async () => { + render(); + await waitFor(() => { + const roleSelectBox = screen.getByTestId('role-select'); + expect(roleSelectBox).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + it("Position TextField Work Correctly", async () => { + render(); + const positionTextField = screen.queryByLabelText('سمت'); + fireEvent.change(positionTextField, {target: {value: 'examplePosition'}}); + await act(() => { + expect(positionTextField).toHaveValue('examplePosition'); + }) + }); + it("Province Select Box Work Correctly", async () => { + render(); + screen.debug() + await waitFor(() => { + expect(screen.queryByText("آذربایجان شرقی")).toBeInTheDocument(); + }); + // const provinceSelectBox = screen.getByTestId('province-select'); + // fireEvent.change(provinceSelectBox, {target: {value: 1}}); + // expect(provinceSelectBox).toHaveValue(1); + }); + // it("Role Select Box Work Correctly", async () => { + // render(); + // const roleSelectBox = screen.getByTestId('role-select'); + // fireEvent.change(roleSelectBox, {target: {value: '1'}}); + // await act(() => { + // expect(roleSelectBox).toHaveValue('1'); + // }) + // }); + }); +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx index e69de29..4e2a764 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx @@ -0,0 +1,12 @@ +import ProvinceAndCity from "./Province&City"; +import PositionAndRole from "./Position&Role"; + +const RestInfo = ({formik}) => { + return ( + <> + + + + ) +} +export default RestInfo \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js index e69de29..bfc7e3b 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js @@ -0,0 +1,42 @@ +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider"; +import CreateContent from "../../../CreateContent"; + +describe("CreateContent Component From Expert Management", () => { + describe("Rendering", () => { + it("UserName TextField Rendered", async () => { + render(); + await waitFor(() => { + const usernameTextField = screen.queryByLabelText('نام کاربری'); + expect(usernameTextField).toBeInTheDocument(); + }); + }); + it("Password TextField Rendered", async () => { + render(); + await waitFor(() => { + const passwordTextField = screen.queryByLabelText('رمز عبور'); + expect(passwordTextField).toBeInTheDocument(); + }); + + }); + }); + describe("Behavioral", () => { + it("Username TextField Work Correctly", async () => { + render(); + const usernameTextField = screen.queryByLabelText('نام کاربری'); + fireEvent.change(usernameTextField, {target: {value: 'exampleUsername'}}); + await act(() => { + expect(usernameTextField).toHaveValue('exampleUsername'); + }) + }); + it("Password TextField Work Correctly", async () => { + render(); + const passwordTextField = screen.queryByLabelText('رمز عبور'); + fireEvent.change(passwordTextField, {target: {value: 'examplePassword'}}); + await act(() => { + expect(passwordTextField).toHaveValue('examplePassword'); + }) + }); + }); +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/index.jsx index 189f997..2455b26 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/index.jsx @@ -1,9 +1,16 @@ import {Grid, IconButton, InputAdornment, TextField} from "@mui/material"; import {useTranslations} from "next-intl"; import {Visibility, VisibilityOff} from "@mui/icons-material"; +import {useState} from "react"; const UserInfo = ({formik}) => { const t = useTranslations(); + const [showPassword, setShowPassword] = useState(false); + + const handleClickShowPassword = () => { + setShowPassword(!showPassword); + }; + return ( <> diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index fee508f..429f468 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -1,156 +1,21 @@ -import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import {render, screen} from "@testing-library/react"; import React from 'react'; import CreateContent from "../../CreateContent"; import MockAppWithProviders from "../../../../../../../../mocks/AppWithProvider"; describe("CreateContent Component From Expert Management", () => { describe("Rendering", () => { - it("Name TextField Rendered", async () => { + it("Password TextField Rendered", () => { render(); - await waitFor(() => { - const nameTextField = screen.queryByLabelText('نام'); - expect(nameTextField).toBeInTheDocument(); - }); + const cancelBtn = screen.queryByText('بستن'); + expect(cancelBtn).toBeInTheDocument(); }); - it("UserName TextField Rendered", async () => { + it("Password TextField Rendered", () => { render(); - await waitFor(() => { - const usernameTextField = screen.queryByLabelText('نام کاربری'); - expect(usernameTextField).toBeInTheDocument(); - }); - }); - it("Email TextField Rendered", async () => { - render(); - await waitFor(() => { - const emailTextField = screen.queryByLabelText('پست الکترونیک'); - expect(emailTextField).toBeInTheDocument(); - }); - }); - it("Phone Number TextField Rendered", async () => { - render(); - await waitFor(() => { - const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); - expect(phoneNumberTextField).toBeInTheDocument(); - }); - }); - it("National Id TextField Rendered", async () => { - render(); - await waitFor(() => { - const nationalIdTextField = screen.queryByLabelText('کد ملی'); - expect(nationalIdTextField).toBeInTheDocument(); - }); - }); - it("Password TextField Rendered", async () => { - render(); - await waitFor(() => { - const passwordTextField = screen.queryByLabelText('رمز عبور'); - expect(passwordTextField).toBeInTheDocument(); - }); - - }); - it("Position TextField Rendered", async () => { - render(); - await waitFor(() => { - const positionTextField = screen.queryByLabelText('سمت'); - expect(positionTextField).toBeInTheDocument(); - }); - }); - it("Province Select Box Rendered", async () => { - render(); - await waitFor(() => { - const provinceSelectBox = screen.getByTestId('province-select'); - expect(provinceSelectBox).toBeInTheDocument(); - }); - }); - it("City Select Box Rendered", async () => { - render(); - await waitFor(() => { - const citySelectBox = screen.getByTestId('city-select'); - expect(citySelectBox).toBeInTheDocument(); - }); - }); - it("Role Select Box Rendered", async () => { - render(); - await waitFor(() => { - const roleSelectBox = screen.getByTestId('role-select'); - expect(roleSelectBox).toBeInTheDocument(); - }); + const cancelBtn = screen.queryByText('ثبت'); + expect(cancelBtn).toBeInTheDocument(); }); }); describe("Behavioral", () => { - it("Name TextField Work Correctly", async () => { - render(); - const nameTextField = screen.queryByLabelText('نام'); - fireEvent.change(nameTextField, {target: {value: 'exampleName'}}); - await act(() => { - expect(nameTextField).toHaveValue('exampleName'); - }) - }); - it("Username TextField Work Correctly", async () => { - render(); - const usernameTextField = screen.queryByLabelText('نام کاربری'); - fireEvent.change(usernameTextField, {target: {value: 'exampleUsername'}}); - await act(() => { - expect(usernameTextField).toHaveValue('exampleUsername'); - }) - }); - it("Email TextField Work Correctly", async () => { - render(); - const emailTextField = screen.queryByLabelText('پست الکترونیک'); - fireEvent.change(emailTextField, {target: {value: 'exampleEmail'}}); - await act(() => { - expect(emailTextField).toHaveValue('exampleEmail'); - }) - }); - it("Phone Number TextField Work Correctly", async () => { - render(); - const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); - fireEvent.change(phoneNumberTextField, {target: {value: 'examplePhoneNumber'}}); - await act(() => { - expect(phoneNumberTextField).toHaveValue('examplePhoneNumber'); - }) - }); - it("National Id TextField Work Correctly", async () => { - render(); - const nationalIdTextField = screen.queryByLabelText('کد ملی'); - fireEvent.change(nationalIdTextField, {target: {value: 'exampleNationalId'}}); - await act(() => { - expect(nationalIdTextField).toHaveValue('exampleNationalId'); - }) - }); - it("Password TextField Work Correctly", async () => { - render(); - const passwordTextField = screen.queryByLabelText('رمز عبور'); - fireEvent.change(passwordTextField, {target: {value: 'examplePassword'}}); - await act(() => { - expect(passwordTextField).toHaveValue('examplePassword'); - }) - }); - it("Position TextField Work Correctly", async () => { - render(); - const positionTextField = screen.queryByLabelText('سمت'); - fireEvent.change(positionTextField, {target: {value: 'examplePosition'}}); - await act(() => { - expect(positionTextField).toHaveValue('examplePosition'); - }) - }); - it("Province Select Box Work Correctly", async () => { - render(); - screen.debug() - await waitFor(() => { - expect(screen.queryByText("آذربایجان شرقی")).toBeInTheDocument(); - }, {timeout: 4000}); - // const provinceSelectBox = screen.getByTestId('province-select'); - // fireEvent.change(provinceSelectBox, {target: {value: 1}}); - // expect(provinceSelectBox).toHaveValue(1); - }); - // it("Role Select Box Work Correctly", async () => { - // render(); - // const roleSelectBox = screen.getByTestId('role-select'); - // fireEvent.change(roleSelectBox, {target: {value: '1'}}); - // await act(() => { - // expect(roleSelectBox).toHaveValue('1'); - // }) - // }); }); }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx index ae6485d..b042da6 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx @@ -1,63 +1,16 @@ -import { - Box, - Button, - Chip, - DialogActions, - DialogContent, - Divider, - FormControl, - FormHelperText, - Grid, - IconButton, - InputAdornment, - InputLabel, - MenuItem, - Select, - TextField, -} from "@mui/material"; +import {Box, Button, Chip, DialogActions, DialogContent, Divider,} from "@mui/material"; import * as Yup from "yup"; import {useTranslations} from "next-intl"; import {useFormik} from "formik"; -import {useState} from "react"; import useRequest from "@/lib/app/hooks/useRequest"; -import {CREATE_EXPERT_MANAGEMENT, GET_CITY_LIST} from "@/core/data/apiRoutes"; -import useRole from "@/lib/app/hooks/useRole"; -import {Visibility, VisibilityOff} from "@mui/icons-material"; -import useProvince from "@/lib/app/hooks/useProvince"; +import {CREATE_EXPERT_MANAGEMENT} from "@/core/data/apiRoutes"; import PersonalInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo"; import UserInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo"; +import RestInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo"; const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { const t = useTranslations(); const requestServer = useRequest() - const [cityList, setCityList] = useState([]); - const [cityTextField, setCityTextField] = useState(t("ExpertMangement.text_field_please_select_province")); - const {provinceList, isLoadingProvinceList, errorProvinceList} = useProvince(); - const {roleList, isLoadingRoleList, errorRoleList} = useRole(); - const [showPassword, setShowPassword] = useState(false); - - const handleClickShowPassword = () => { - setShowPassword(!showPassword); - }; - - function getCities(province_id) { - formik.setFieldTouched("city_id", false, false); - formik.setFieldValue("city_id", "") - setCityTextField(t("ExpertMangement.text_field_loading_cities_list")) - requestServer(`${GET_CITY_LIST}?province_id=${province_id}`, "get", {auth: true, notification: false}) - .then(({data}) => { - const result = data.data; - const formattedData = result.map((city, index) => ({ - id: index, - name: city.name, - value: city.id, - })); - setCityList(formattedData); - setCityTextField(t("ExpertMangement.text_field_city_id")) - }).catch(() => { - setCityTextField(t("ExpertMangement.text_field_error_fetching_cities")) - }); - } const validationSchema = Yup.object().shape({ name: Yup.string().required(t("ExpertMangement.error_message_name")), @@ -125,7 +78,7 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { /> - + {!formik ? null : } { /> - + {!formik ? null : } { /> - - - - {t("ExpertMangement.text_field_province_id")} - - - {formik.touched.province_id && formik.errors.province_id ? formik.errors.province_id : ""} - - - - - - {cityTextField} - - - {formik.touched.city_id && formik.errors.city_id ? formik.errors.city_id : ""} - - - - - - - - - - - {t("ExpertMangement.text_field_role_id")} - - - {formik.touched.role_id && formik.errors.role_id ? formik.errors.role_id : ""} - - - - + {!formik ? null : } + + ) diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index 6e604c1..c56ce21 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -1,5 +1,9 @@ const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL; +//login +export const GET_USER_TOKEN = BASE_URL + "/api/auth/login"; +//end login + // role list export const GET_ROLE_LIST = BASE_URL + "/dashboard/roles/list"; // role list @@ -9,10 +13,6 @@ export const GET_PROVINCE_LIST = BASE_URL + "/api/provinces"; export const GET_CITY_LIST = BASE_URL + "/api/cities"; // province/city list -//login -export const GET_USER_TOKEN = BASE_URL + "/api/auth/login"; -//end login - //change password export const SET_USER_PASSWORD = BASE_URL + "/dashboard/profile/change_password"; //end change password From 45f2597dacb96ef75575c7ffa51a6ba65d0bb511 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Tue, 10 Oct 2023 17:30:22 +0330 Subject: [PATCH 07/20] CFE-3 complete and debug all structure and write validation part of test for inputs and work on select box of mui after this --- mocks/handler.js | 10 +- public/locales/fa/app.json | 5 +- .../expert-management/DataTable/index.jsx | 21 +--- .../PersonalInfo/__tests__/index.test.js | 98 +++++++++++++++++-- .../PositionAndRole/__tests__/index.test.js | 90 +++++++++++++++++ .../index.jsx} | 1 + .../RestInfo/Province/__tests__/index.test.js | 62 ++++++++++++ .../{Province&City.jsx => Province/index.jsx} | 56 +---------- .../RestInfo/__tests__/index.test.js | 65 ------------ .../CreateContent/RestInfo/index.jsx | 6 +- .../UserInfo/__test__/index.test.js | 92 ++++++++++++++++- .../CreateContent/__tests__/index.test.js | 34 ++++++- .../Form/CreateForm/CreateContent/index.jsx | 11 +-- src/core/data/apiRoutes.js | 11 +-- 14 files changed, 387 insertions(+), 175 deletions(-) create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js rename src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/{Position&Role.jsx => PositionAndRole/index.jsx} (98%) create mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js rename src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/{Province&City.jsx => Province/index.jsx} (50%) delete mode 100644 src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js diff --git a/mocks/handler.js b/mocks/handler.js index 45183f9..a35551c 100644 --- a/mocks/handler.js +++ b/mocks/handler.js @@ -28,13 +28,13 @@ export const handler = [ data: [ { id: 1, - name: "passenger_office_chief", - name_fa: "رئیس اداره مسافری استان" + name: "admin", + name_fa: "ادمین" }, { - id: 4, - name: "province_manager", - name_fa: "مدیر کل استانی" + id: 2, + name: "manager", + name_fa: "مدیر" } ] })) diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index a7361da..08ce5fd 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -129,8 +129,7 @@ "phone_number": "شماره همراه", "national_id": "کد ملی", "position": "سمت", - "province_name": "استان", - "city_name": "شهر", + "province_fa": "استان", "role_name": "نقش", "updated_at": "آخرین بروزرسانی", "create": "افزودن کارشناس", @@ -145,7 +144,6 @@ "text_field_password": "رمز عبور", "text_field_position": "سمت", "text_field_province_id": "استان", - "text_field_city_id": "شهر", "text_field_role_id": "نقش", "text_field_loading_provinces_list": "درحال دریافت شهر ها", "text_field_error_fetching_provinces": "خطا در دریافت شهر ها", @@ -164,7 +162,6 @@ "error_message_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد", "error_message_position": "سمت خود را وارد کنید", "error_message_province_id": "استان خود را وارد کنید", - "error_message_city_id": "شهر خود را وارد کنید", "error_message_role_id": "نقش خود را وارد کنید", "error_message_new_password": "رمز عبور جدید را وارد کنید", "error_message_new_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد", diff --git a/src/components/dashboard/expert-management/DataTable/index.jsx b/src/components/dashboard/expert-management/DataTable/index.jsx index 67bb64f..b3b4564 100644 --- a/src/components/dashboard/expert-management/DataTable/index.jsx +++ b/src/components/dashboard/expert-management/DataTable/index.jsx @@ -6,6 +6,7 @@ import TableRowActions from "../TableRowActions"; import {Box, Typography} from "@mui/material"; import {useTranslations} from "next-intl"; import {useMemo} from "react"; +import moment from "jalali-moment"; function ExpertManagementDataTable() { const t = useTranslations(); @@ -31,7 +32,7 @@ function ExpertManagementDataTable() { ), }, { - accessorFn: (row) => row.name, + accessorFn: (row) => row.full_name, id: "name", header: t("ExpertMangement.name"), enableColumnFilter: true, @@ -103,21 +104,9 @@ function ExpertManagementDataTable() { ), }, { - accessorFn: (row) => row.province_name, - id: "province_name", - header: t("ExpertMangement.province_name"), - enableColumnFilter: false, - datatype: "text", - filterFn: "contains", - columnFilterModeOptions: ["contains", "equals", "notEquals"], - Cell: ({renderedCellValue}) => ( - {renderedCellValue} - ), - }, - { - accessorFn: (row) => row.city_name, - id: "city_name", - header: t("ExpertMangement.city_name"), + accessorFn: (row) => row.province_fa, + id: "province_fa", + header: t("ExpertMangement.province_fa"), enableColumnFilter: false, datatype: "text", filterFn: "contains", diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js index 66aba9e..3c11418 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js @@ -1,33 +1,63 @@ import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider"; -import CreateContent from "../../../CreateContent"; +import * as Yup from "yup"; +import {Formik} from "formik"; +import PersonalInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo"; +import {useTranslations} from "next-intl"; + + +const CreateFormMock = ({Component}) => { + const t = useTranslations(); + const validationSchema = Yup.object().shape({ + name: Yup.string().required(t("ExpertMangement.error_message_name")), + email: Yup.string().required(t("ExpertMangement.error_message_email")), + phone_number: Yup.string().required(t("ExpertMangement.error_message_phone_number")), + national_id: Yup.string().required(t("ExpertMangement.error_message_national_id")) + }); + return ( + { + }} + > + {formikProps => ()} + + ); +}; + describe("PersonalInfo Component From Expert Management", () => { describe("Rendering", () => { it("Name TextField Rendered", async () => { - render(); + render(); await waitFor(() => { const nameTextField = screen.queryByLabelText('نام'); expect(nameTextField).toBeInTheDocument(); }); }); it("Email TextField Rendered", async () => { - render(); + render(); await waitFor(() => { const emailTextField = screen.queryByLabelText('پست الکترونیک'); expect(emailTextField).toBeInTheDocument(); }); }); it("Phone Number TextField Rendered", async () => { - render(); + render(); await waitFor(() => { const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); expect(phoneNumberTextField).toBeInTheDocument(); }); }); it("National Id TextField Rendered", async () => { - render(); + render(); await waitFor(() => { const nationalIdTextField = screen.queryByLabelText('کد ملی'); expect(nationalIdTextField).toBeInTheDocument(); @@ -36,7 +66,7 @@ describe("PersonalInfo Component From Expert Management", () => { }); describe("Behavioral", () => { it("Name TextField Work Correctly", async () => { - render(); + render(); const nameTextField = screen.queryByLabelText('نام'); fireEvent.change(nameTextField, {target: {value: 'exampleName'}}); await act(() => { @@ -44,7 +74,7 @@ describe("PersonalInfo Component From Expert Management", () => { }) }); it("Email TextField Work Correctly", async () => { - render(); + render(); const emailTextField = screen.queryByLabelText('پست الکترونیک'); fireEvent.change(emailTextField, {target: {value: 'exampleEmail'}}); await act(() => { @@ -52,7 +82,7 @@ describe("PersonalInfo Component From Expert Management", () => { }) }); it("Phone Number TextField Work Correctly", async () => { - render(); + render(); const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); fireEvent.change(phoneNumberTextField, {target: {value: 'examplePhoneNumber'}}); await act(() => { @@ -60,7 +90,7 @@ describe("PersonalInfo Component From Expert Management", () => { }) }); it("National Id TextField Work Correctly", async () => { - render(); + render(); const nationalIdTextField = screen.queryByLabelText('کد ملی'); fireEvent.change(nationalIdTextField, {target: {value: 'exampleNationalId'}}); await act(() => { @@ -68,4 +98,54 @@ describe("PersonalInfo Component From Expert Management", () => { }) }); }); + describe("validation", () => { + it('Should See Error When Name Input Is Empty', async () => { + render(); + + const nameInput = screen.queryByLabelText('نام'); + + fireEvent.change(nameInput, {target: {value: ''}}); + fireEvent.blur(nameInput); + + await waitFor(() => { + expect(screen.queryByText("نام خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When Email Input Is Empty', async () => { + render(); + + const emailInput = screen.queryByLabelText('پست الکترونیک'); + + fireEvent.change(emailInput, {target: {value: ''}}); + fireEvent.blur(emailInput); + + await waitFor(() => { + expect(screen.queryByText("پست الکترونیک خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When Phone Number Input Is Empty', async () => { + render(); + + const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + + fireEvent.change(phoneNumberInput, {target: {value: ''}}); + fireEvent.blur(phoneNumberInput); + + await waitFor(() => { + expect(screen.queryByText("شماره همراه خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When National Id Input Is Empty', async () => { + render(); + + const nationalIdInput = screen.queryByLabelText('کد ملی'); + + fireEvent.change(nationalIdInput, {target: {value: ''}}); + fireEvent.blur(nationalIdInput); + + await waitFor(() => { + expect(screen.queryByText("کد ملی خود را وارد کنید")).toBeInTheDocument() + }); + }); + }) }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js new file mode 100644 index 0000000..865bc7d --- /dev/null +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js @@ -0,0 +1,90 @@ +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import {Formik} from "formik"; +import MockAppWithProviders from "../../../../../../../../../../mocks/AppWithProvider"; +import PositionAndRole from "../../PositionAndRole"; + +const CreateFormMock = ({Component}) => { + const t = useTranslations(); + const validationSchema = Yup.object().shape({ + position: Yup.string().required(t("ExpertMangement.error_message_position")), + role_id: Yup.string().required(t("ExpertMangement.error_message_role_id")) + }); + return ( + { + }} + > + {formikProps => ()} + + ); +}; + +describe("CreateContent Component From Expert Management", () => { + describe("Rendering", () => { + it("Position TextField Rendered", async () => { + render(); + await waitFor(() => { + const positionTextField = screen.queryByLabelText('سمت'); + expect(positionTextField).toBeInTheDocument(); + }); + }); + it("Role Select Box Rendered", async () => { + render(); + await waitFor(() => { + const roleSelectBox = screen.getByTestId('role-select'); + expect(roleSelectBox).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + it("Position TextField Work Correctly", async () => { + render(); + const positionTextField = screen.queryByLabelText('سمت'); + fireEvent.change(positionTextField, {target: {value: 'examplePosition'}}); + await waitFor(() => { + expect(positionTextField).toHaveValue('examplePosition'); + }) + }); + // it("Role Select Box Work Correctly", async () => { + // render(); + // await waitFor(() => { + // expect(screen.queryByText("ادمین")).toBeInTheDocument(); + // }, {timeout: 3000}); + // const roleSelectBox = screen.getByTestId('role-select'); + // }); + }); + describe("validation", () => { + it('Should See Error When Position Input Is Empty', async () => { + render(); + + const positionInput = screen.queryByLabelText('سمت'); + + fireEvent.change(positionInput, {target: {value: ''}}); + fireEvent.blur(positionInput); + + await waitFor(() => { + expect(screen.queryByText("سمت خود را وارد کنید")).toBeInTheDocument() + }); + }); + // it('Should See Error When Role Select Is Empty', async () => { + // render(); + // + // const roleSelect = screen.queryByLabelText('نقش'); + // + // fireEvent.change(roleSelect, {target: {value: 1}}); + // fireEvent.blur(roleSelect); + // + // await waitFor(() => { + // expect(screen.queryByText("نقش خود را وارد کنید")).toBeInTheDocument() + // }); + // }); + }) +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Position&Role.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx similarity index 98% rename from src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Position&Role.jsx rename to src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx index 47d594c..305296e 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Position&Role.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx @@ -2,6 +2,7 @@ import {FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, TextFie import {useTranslations} from "next-intl"; import useRequest from "@/lib/app/hooks/useRequest"; import useRole from "@/lib/app/hooks/useRole"; +import {log} from "next/dist/server/typescript/utils"; const PositionAndRole = ({formik}) => { const t = useTranslations(); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js new file mode 100644 index 0000000..2d7f576 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js @@ -0,0 +1,62 @@ +import {fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import {Formik} from "formik"; +import Province from "../../Province"; +import MockAppWithProviders from "../../../../../../../../../../mocks/AppWithProvider"; + +const CreateFormMock = ({Component}) => { + const t = useTranslations(); + const validationSchema = Yup.object().shape({ + province_id: Yup.string().required(t("ExpertMangement.error_message_province_id")), + }); + return ( + { + }} + > + {formikProps => ()} + + ); +}; + +describe("CreateContent Component From Expert Management", () => { + describe("Rendering", () => { + it("Province Select Box Rendered", async () => { + render(); + await waitFor(() => { + const provinceSelectBox = screen.getByTestId('province-select'); + expect(provinceSelectBox).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + it("Province Select Box Work Correctly", async () => { + render(); + const provinceSelectBox = screen.getByTestId('province-select'); + fireEvent.click(provinceSelectBox) + await waitFor(() => { + expect(screen.queryByText("آذربایجان شرقی")).toBeInTheDocument(); + }); + }); + }); + describe("validation", () => { + // it('Should See Error When Province Select Is Empty', async () => { + // render(); + // + // const provinceSelect = screen.queryByLabelText('استان'); + // + // fireEvent.change(provinceSelect, {target: {value: 1}}); + // fireEvent.blur(provinceSelect); + // + // await waitFor(() => { + // expect(screen.queryByText("استان خود را وارد کنید")).toBeInTheDocument() + // }); + // }); + }) +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province&City.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx similarity index 50% rename from src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province&City.jsx rename to src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx index 46245b2..550b8d8 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province&City.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx @@ -2,35 +2,13 @@ import {FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select} from "@ import {useTranslations} from "next-intl"; import {useState} from "react"; import useProvince from "@/lib/app/hooks/useProvince"; -import {GET_CITY_LIST} from "@/core/data/apiRoutes"; import useRequest from "@/lib/app/hooks/useRequest"; -const ProvinceAndCity = ({formik}) => { +const Province = ({formik}) => { const t = useTranslations(); const requestServer = useRequest() - const [cityList, setCityList] = useState([]); - const [cityTextField, setCityTextField] = useState(t("ExpertMangement.text_field_please_select_province")); const {provinceList, isLoadingProvinceList, errorProvinceList} = useProvince(); - function getCities(province_id) { - formik.setFieldTouched("city_id", false, false); - formik.setFieldValue("city_id", "") - setCityTextField(t("ExpertMangement.text_field_loading_cities_list")) - requestServer(`${GET_CITY_LIST}?province_id=${province_id}`, "get", {auth: true, notification: false}) - .then(({data}) => { - const result = data.data; - const formattedData = result.map((city, index) => ({ - id: index, - name: city.name, - value: city.id, - })); - setCityList(formattedData); - setCityTextField(t("ExpertMangement.text_field_city_id")) - }).catch(() => { - setCityTextField(t("ExpertMangement.text_field_error_fetching_cities")) - }); - } - return ( @@ -48,7 +26,6 @@ const ProvinceAndCity = ({formik}) => { value={formik.values.province_id} onChange={(e) => { formik.setFieldValue("province_id", e.target.value); - getCities(e.target.value) }} onBlur={formik.handleBlur} fullWidth @@ -75,36 +52,7 @@ const ProvinceAndCity = ({formik}) => { - - - {cityTextField} - - - {formik.touched.city_id && formik.errors.city_id ? formik.errors.city_id : ""} - - - ) } -export default ProvinceAndCity \ No newline at end of file +export default Province \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js deleted file mode 100644 index 1139c9c..0000000 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/__tests__/index.test.js +++ /dev/null @@ -1,65 +0,0 @@ -import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; -import React from 'react'; -import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider"; -import CreateContent from "../../../CreateContent"; - -describe("CreateContent Component From Expert Management", () => { - describe("Rendering", () => { - it("Position TextField Rendered", async () => { - render(); - await waitFor(() => { - const positionTextField = screen.queryByLabelText('سمت'); - expect(positionTextField).toBeInTheDocument(); - }); - }); - it("Province Select Box Rendered", async () => { - render(); - await waitFor(() => { - const provinceSelectBox = screen.getByTestId('province-select'); - expect(provinceSelectBox).toBeInTheDocument(); - }); - }); - it("City Select Box Rendered", async () => { - render(); - await waitFor(() => { - const citySelectBox = screen.getByTestId('city-select'); - expect(citySelectBox).toBeInTheDocument(); - }); - }); - it("Role Select Box Rendered", async () => { - render(); - await waitFor(() => { - const roleSelectBox = screen.getByTestId('role-select'); - expect(roleSelectBox).toBeInTheDocument(); - }); - }); - }); - describe("Behavioral", () => { - it("Position TextField Work Correctly", async () => { - render(); - const positionTextField = screen.queryByLabelText('سمت'); - fireEvent.change(positionTextField, {target: {value: 'examplePosition'}}); - await act(() => { - expect(positionTextField).toHaveValue('examplePosition'); - }) - }); - it("Province Select Box Work Correctly", async () => { - render(); - screen.debug() - await waitFor(() => { - expect(screen.queryByText("آذربایجان شرقی")).toBeInTheDocument(); - }); - // const provinceSelectBox = screen.getByTestId('province-select'); - // fireEvent.change(provinceSelectBox, {target: {value: 1}}); - // expect(provinceSelectBox).toHaveValue(1); - }); - // it("Role Select Box Work Correctly", async () => { - // render(); - // const roleSelectBox = screen.getByTestId('role-select'); - // fireEvent.change(roleSelectBox, {target: {value: '1'}}); - // await act(() => { - // expect(roleSelectBox).toHaveValue('1'); - // }) - // }); - }); -}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx index 4e2a764..072c096 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/index.jsx @@ -1,10 +1,10 @@ -import ProvinceAndCity from "./Province&City"; -import PositionAndRole from "./Position&Role"; +import Province from "./Province"; +import PositionAndRole from "./PositionAndRole"; const RestInfo = ({formik}) => { return ( <> - + ) diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js index bfc7e3b..7f10a99 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js @@ -1,19 +1,49 @@ import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider"; -import CreateContent from "../../../CreateContent"; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import {Formik} from "formik"; +import UserInfo from "../../UserInfo"; +import PersonalInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo"; + +const CreateFormMock = ({Component}) => { + const t = useTranslations(); + const validationSchema = Yup.object().shape({ + username: Yup.string().required(t("ExpertMangement.error_message_username")), + password: Yup.string() + .required(t("ExpertMangement.error_message_password")) + .matches( + /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/, + t("ExpertMangement.error_message_password_regex") + ), + }); + return ( + { + }} + > + {formikProps => ()} + + ); +}; describe("CreateContent Component From Expert Management", () => { describe("Rendering", () => { it("UserName TextField Rendered", async () => { - render(); + render(); await waitFor(() => { const usernameTextField = screen.queryByLabelText('نام کاربری'); expect(usernameTextField).toBeInTheDocument(); }); }); it("Password TextField Rendered", async () => { - render(); + render(); await waitFor(() => { const passwordTextField = screen.queryByLabelText('رمز عبور'); expect(passwordTextField).toBeInTheDocument(); @@ -23,7 +53,7 @@ describe("CreateContent Component From Expert Management", () => { }); describe("Behavioral", () => { it("Username TextField Work Correctly", async () => { - render(); + render(); const usernameTextField = screen.queryByLabelText('نام کاربری'); fireEvent.change(usernameTextField, {target: {value: 'exampleUsername'}}); await act(() => { @@ -31,7 +61,7 @@ describe("CreateContent Component From Expert Management", () => { }) }); it("Password TextField Work Correctly", async () => { - render(); + render(); const passwordTextField = screen.queryByLabelText('رمز عبور'); fireEvent.change(passwordTextField, {target: {value: 'examplePassword'}}); await act(() => { @@ -39,4 +69,56 @@ describe("CreateContent Component From Expert Management", () => { }) }); }); + describe("validation", () => { + it('Should See Error When Username Input Is Empty', async () => { + render(); + + const usernameInput = screen.queryByLabelText('نام کاربری'); + + fireEvent.change(usernameInput, {target: {value: ''}}); + fireEvent.blur(usernameInput); + + await waitFor(() => { + expect(screen.queryByText("نام کاربری خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When Password Input Is Empty', async () => { + render(); + + const passwordInput = screen.queryByLabelText('رمز عبور'); + + fireEvent.change(passwordInput, {target: {value: ''}}); + fireEvent.blur(passwordInput); + + await waitFor(() => { + expect(screen.queryByText("رمز عبور خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When Password Field Is Not On Correct Format', async () => { + render(); + + const passwordInput = screen.queryByLabelText('رمز عبور'); + + // check without text or symbol + fireEvent.change(passwordInput, {target: {value: '12345678'}}); + fireEvent.blur(passwordInput); + await waitFor(() => { + expect(screen.queryByText("رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد")).toBeInTheDocument() + }); + + // check without number + fireEvent.change(passwordInput, {target: {value: 'abcdefgh'}}); + fireEvent.blur(passwordInput); + await waitFor(() => { + expect(screen.queryByText("رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد")).toBeInTheDocument() + }); + + // check under 8 character + fireEvent.change(passwordInput, {target: {value: '11Sa'}}); + fireEvent.blur(passwordInput); + await waitFor(() => { + expect(screen.queryByText("رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد")).toBeInTheDocument() + }); + }); + }) }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index 429f468..3180159 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -1,7 +1,8 @@ -import {render, screen} from "@testing-library/react"; +import {fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import CreateContent from "../../CreateContent"; import MockAppWithProviders from "../../../../../../../../mocks/AppWithProvider"; +import CreateForm from "@/components/dashboard/expert-management/Form/CreateForm"; describe("CreateContent Component From Expert Management", () => { describe("Rendering", () => { @@ -18,4 +19,35 @@ describe("CreateContent Component From Expert Management", () => { }); describe("Behavioral", () => { }); + // describe("Form Submission", () => { + // it('Should enable the submit button when the inputs are valid', async () => { + // render(); + // + // const submitButton = screen.getByRole('button', {name: 'ثبت'}); + // + // const nameInput = screen.queryByLabelText('نام'); + // const usernameInput = screen.queryByLabelText('نام کاربری'); + // const emailInput = screen.queryByLabelText('پست الکترونیک'); + // const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + // const nationalIdInput = screen.queryByLabelText('کد ملی'); + // const passwordInput = screen.queryByLabelText('رمز عبور'); + // const positionInput = screen.queryByLabelText('سمت'); + // const provinceInput = screen.queryByLabelText('استان'); + // const roleInput = screen.queryByLabelText('نقش'); + // + // fireEvent.change(nameInput, {target: {value: 'nameTest'}}); + // fireEvent.change(usernameInput, {target: {value: 'usernameTest'}}); + // fireEvent.change(emailInput, {target: {value: 'emailTest'}}); + // fireEvent.change(phoneNumberInput, {target: {value: 'phoneNumberTest'}}); + // fireEvent.change(nationalIdInput, {target: {value: 'nationalIdTest'}}); + // fireEvent.change(passwordInput, {target: {value: 'passwordTest'}}); + // fireEvent.change(positionInput, {target: {value: 'positionTest'}}); + // fireEvent.change(provinceInput, {target: {value: 1}}); + // fireEvent.change(roleInput, {target: {value: 1}}); + // + // await waitFor(() => { + // expect(submitButton).not.toBeDisabled(); + // }); + // }); + // }) }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx index b042da6..bc5c157 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx @@ -26,7 +26,6 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { ), position: Yup.string().required(t("ExpertMangement.error_message_position")), province_id: Yup.string().required(t("ExpertMangement.error_message_province_id")), - city_id: Yup.string().required(t("ExpertMangement.error_message_city_id")), role_id: Yup.string().required(t("ExpertMangement.error_message_role_id")) }); @@ -40,7 +39,6 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { password: "", position: "", province_id: "", - city_id: "", role_id: "" }, validationSchema, @@ -53,7 +51,6 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { formData.append("username", values.username); formData.append("password", values.password); formData.append("province_id", values.province_id); - formData.append("city_id", values.city_id); formData.append("position", values.position); formData.append("role_id", values.role_id); @@ -78,7 +75,7 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { /> - {!formik ? null : } + { /> - {!formik ? null : } + { /> - {!formik ? null : } + diff --git a/src/core/data/apiRoutes.js b/src/core/data/apiRoutes.js index c56ce21..818272d 100644 --- a/src/core/data/apiRoutes.js +++ b/src/core/data/apiRoutes.js @@ -5,13 +5,12 @@ export const GET_USER_TOKEN = BASE_URL + "/api/auth/login"; //end login // role list -export const GET_ROLE_LIST = BASE_URL + "/dashboard/roles/list"; +export const GET_ROLE_LIST = BASE_URL + "/api/roles/list"; // role list -// province/city list +// province list export const GET_PROVINCE_LIST = BASE_URL + "/api/provinces"; -export const GET_CITY_LIST = BASE_URL + "/api/cities"; -// province/city list +// province list //change password export const SET_USER_PASSWORD = BASE_URL + "/dashboard/profile/change_password"; @@ -22,6 +21,6 @@ export const GET_USER_ROUTE = BASE_URL + "/api/profile/info"; //user data //expert management -export const GET_EXPERT_MANAGEMENT_LIST = BASE_URL + "/dashboard/experts/show"; -export const CREATE_EXPERT_MANAGEMENT = BASE_URL + "/dashboard/experts/store"; +export const GET_EXPERT_MANAGEMENT_LIST = BASE_URL + "/api/users"; +export const CREATE_EXPERT_MANAGEMENT = BASE_URL + "/api/users"; //expert management \ No newline at end of file From a76c50b59f3f44efe0ca52a6b72a658471fca8cb Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Wed, 11 Oct 2023 15:17:12 +0330 Subject: [PATCH 08/20] CFE-3 solve problem of select box --- .../PositionAndRole/__tests__/index.test.js | 52 +++++++++++-------- .../RestInfo/PositionAndRole/index.jsx | 6 ++- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js index 865bc7d..17be452 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js @@ -1,10 +1,11 @@ -import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import {act, findByRole, findByText, fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import {useTranslations} from "next-intl"; import * as Yup from "yup"; import {Formik} from "formik"; import MockAppWithProviders from "../../../../../../../../../../mocks/AppWithProvider"; import PositionAndRole from "../../PositionAndRole"; +import {MenuItem, Select} from "@mui/material"; const CreateFormMock = ({Component}) => { const t = useTranslations(); @@ -38,9 +39,9 @@ describe("CreateContent Component From Expert Management", () => { }); it("Role Select Box Rendered", async () => { render(); + const roleSelect = screen.getByTestId('select-box'); await waitFor(() => { - const roleSelectBox = screen.getByTestId('role-select'); - expect(roleSelectBox).toBeInTheDocument(); + expect(roleSelect).toBeInTheDocument(); }); }); }); @@ -53,13 +54,18 @@ describe("CreateContent Component From Expert Management", () => { expect(positionTextField).toHaveValue('examplePosition'); }) }); - // it("Role Select Box Work Correctly", async () => { - // render(); - // await waitFor(() => { - // expect(screen.queryByText("ادمین")).toBeInTheDocument(); - // }, {timeout: 3000}); - // const roleSelectBox = screen.getByTestId('role-select'); - // }); + it("Role Select Box Work Correctly", async () => { + render(); + const roleSelect = screen.getByTestId("option-opener"); + await waitFor(() => { + expect(roleSelect).toBeInTheDocument(); + }); + fireEvent.mouseDown(roleSelect); + await waitFor(() => { + const selectItem = screen.queryByText("ادمین"); + expect(selectItem).toBeInTheDocument(); + }); + }); }); describe("validation", () => { it('Should See Error When Position Input Is Empty', async () => { @@ -74,17 +80,19 @@ describe("CreateContent Component From Expert Management", () => { expect(screen.queryByText("سمت خود را وارد کنید")).toBeInTheDocument() }); }); - // it('Should See Error When Role Select Is Empty', async () => { - // render(); - // - // const roleSelect = screen.queryByLabelText('نقش'); - // - // fireEvent.change(roleSelect, {target: {value: 1}}); - // fireEvent.blur(roleSelect); - // - // await waitFor(() => { - // expect(screen.queryByText("نقش خود را وارد کنید")).toBeInTheDocument() - // }); - // }); + it('Should See Error When Role Select Is Empty', async () => { + render(); + const roleInput = screen.getByTestId("input-role-id") + const roleSelectOpener = await waitFor(() => screen.getByTestId("option-opener")); + + fireEvent.mouseDown(roleSelectOpener); + + const selectItem = await waitFor(() => screen.queryByText("ادمین")); + expect(selectItem).toBeInTheDocument(); + fireEvent.click(selectItem); + await waitFor(() => { + expect(roleInput.value).toBe('1') + }); + }); }) }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx index 305296e..5af2a8b 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx @@ -36,11 +36,15 @@ const PositionAndRole = ({formik}) => { { + formik.setFieldValue("gender", e.target.value); + }} + inputProps={{ + "data-testid": "input-gender" + }} + data-testid="select-box" + SelectDisplayProps={{"data-testid": 'option-opener-gender'}} + onBlur={formik.handleBlur} + fullWidth + variant="outlined" + > + {( + genderList.map((item) => ( + + {item.name_fa} + + )) + )} + + + {formik.touched.gender && formik.errors.gender ? formik.errors.gender : ""} + + + ) } diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js index e788764..0e6cf4b 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js @@ -11,13 +11,13 @@ const CreateFormMock = ({Component}) => { const t = useTranslations(); const validationSchema = Yup.object().shape({ position: Yup.string().required(t("ExpertMangement.error_message_position")), - role_id: Yup.string().required(t("ExpertMangement.error_message_role_id")) + roles: Yup.string().required(t("ExpertMangement.error_message_roles")) }); return ( { @@ -56,7 +56,7 @@ describe("CreateContent Component From Expert Management", () => { }); it("Role Select Box Work Correctly", async () => { render(); - const roleSelect = screen.getByTestId("option-opener"); + const roleSelect = screen.getByTestId("option-opener-role"); await waitFor(() => { expect(roleSelect).toBeInTheDocument(); }); @@ -83,7 +83,7 @@ describe("CreateContent Component From Expert Management", () => { it('Should Select An Item With Valid Value of role', async () => { render(); const roleInput = screen.getByTestId("input-role-id") - const roleSelectOpener = await waitFor(() => screen.getByTestId("option-opener")); + const roleSelectOpener = await waitFor(() => screen.getByTestId("option-opener-role")); fireEvent.mouseDown(roleSelectOpener); const selectItem = await waitFor(() => screen.queryByText("ادمین")); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx index 5af2a8b..6befbff 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/index.jsx @@ -28,15 +28,15 @@ const PositionAndRole = ({formik}) => { - {t("ExpertMangement.text_field_role_id")} + {t("ExpertMangement.text_field_roles")} - {formik.touched.role_id && formik.errors.role_id ? formik.errors.role_id : ""} + {formik.touched.roles && formik.errors.roles ? formik.errors.roles : ""} diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js index 08fab78..354df01 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js @@ -41,7 +41,7 @@ describe("CreateContent Component From Expert Management", () => { it("Province Select Box Work Correctly", async () => { render(); const provinceSelectBox = screen.getByTestId('select-box'); - const provinceSelectOpener = await waitFor(() => screen.getByTestId("option-opener")); + const provinceSelectOpener = await waitFor(() => screen.getByTestId("option-opener-province")); await waitFor(() => { expect(provinceSelectBox).toBeInTheDocument(); @@ -59,7 +59,7 @@ describe("CreateContent Component From Expert Management", () => { it('Should Select An Item With Valid Value of province', async () => { render(); const provinceInput = screen.getByTestId("input-province-id") - const provinceSelectOpener = await waitFor(() => screen.getByTestId("option-opener")); + const provinceSelectOpener = await waitFor(() => screen.getByTestId("option-opener-province")); fireEvent.mouseDown(provinceSelectOpener); const selectItem = await waitFor(() => screen.queryByText("آذربایجان شرقی")); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx index f9e7c94..4c8995c 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx @@ -30,7 +30,7 @@ const Province = ({formik}) => { "data-testid": "input-province-id" }} data-testid="select-box" - SelectDisplayProps={{"data-testid": 'option-opener'}} + SelectDisplayProps={{"data-testid": 'option-opener-province'}} onBlur={formik.handleBlur} fullWidth variant="outlined" diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index 6576125..cccc604 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -21,9 +21,9 @@ describe("CreateContent Component From Expert Management", () => { }); describe("Form Submission", () => { it('Should enable the submit button when the inputs are valid', async () => { - render(); + render(); - const submitButton = screen.getByText('ثبت'); + const submitButton = screen.queryByText('ثبت'); const nameInput = screen.queryByLabelText('نام'); const usernameInput = screen.queryByLabelText('نام کاربری'); @@ -32,8 +32,10 @@ describe("CreateContent Component From Expert Management", () => { const nationalIdInput = screen.queryByLabelText('کد ملی'); const passwordInput = screen.queryByLabelText('رمز عبور'); const positionInput = screen.queryByLabelText('سمت'); - // const provinceInput = screen.queryByLabelText('استان'); - // const roleInput = screen.queryByLabelText('نقش'); + const provinceSelectOpener = screen.getByTestId("option-opener-province"); + const roleSelectOpener = screen.getByTestId("option-opener-role"); + fireEvent.mouseDown(provinceSelectOpener); + fireEvent.mouseDown(roleSelectOpener); fireEvent.change(nameInput, {target: {value: 'nameTest'}}); fireEvent.change(usernameInput, {target: {value: 'usernameTest'}}); @@ -42,8 +44,10 @@ describe("CreateContent Component From Expert Management", () => { fireEvent.change(nationalIdInput, {target: {value: 'nationalIdTest'}}); fireEvent.change(passwordInput, {target: {value: 'passwordTest'}}); fireEvent.change(positionInput, {target: {value: 'positionTest'}}); - // fireEvent.change(provinceInput, {target: {value: 1}}); - // fireEvent.change(roleInput, {target: {value: 1}}); + const selectItemProvince = await waitFor(() => screen.queryByText("آذربایجان شرقی")); + fireEvent.click(selectItemProvince); + const selectItemRole = await waitFor(() => screen.queryByText("ادمین")); + fireEvent.click(selectItemRole); await waitFor(() => { expect(submitButton).not.toBeDisabled(); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx index bc5c157..a7e0ef5 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx @@ -13,10 +13,12 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { const requestServer = useRequest() const validationSchema = Yup.object().shape({ - name: Yup.string().required(t("ExpertMangement.error_message_name")), + full_name: Yup.string().required(t("ExpertMangement.error_message_full_name")), username: Yup.string().required(t("ExpertMangement.error_message_username")), email: Yup.string().required(t("ExpertMangement.error_message_email")), phone_number: Yup.string().required(t("ExpertMangement.error_message_phone_number")), + telephone_id: Yup.string().required(t("ExpertMangement.error_message_telephone_id")), + gender: Yup.string().required(t("ExpertMangement.error_message_gender")), national_id: Yup.string().required(t("ExpertMangement.error_message_national_id")), password: Yup.string() .required(t("ExpertMangement.error_message_password")) @@ -26,33 +28,37 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { ), position: Yup.string().required(t("ExpertMangement.error_message_position")), province_id: Yup.string().required(t("ExpertMangement.error_message_province_id")), - role_id: Yup.string().required(t("ExpertMangement.error_message_role_id")) + roles: Yup.string().required(t("ExpertMangement.error_message_roles")) }); const formik = useFormik({ initialValues: { - name: "", + full_name: "", username: "", email: "", phone_number: "", + telephone_id: "", + gender: "", national_id: "", password: "", position: "", province_id: "", - role_id: "" + roles: "" }, validationSchema, onSubmit: (values, {setSubmitting}) => { const formData = new FormData(); - formData.append("name", values.name); + formData.append("full_name", values.full_name); formData.append("national_id", values.national_id); formData.append("phone_number", values.phone_number); + formData.append("telephone_id", values.telephone_id); + formData.append("gender", values.gender); formData.append("email", values.email); formData.append("username", values.username); formData.append("password", values.password); formData.append("province_id", values.province_id); formData.append("position", values.position); - formData.append("role_id", values.role_id); + formData.append("roles", values.roles); requestServer(`${CREATE_EXPERT_MANAGEMENT}`, 'post', {auth: true, data: formData}) .then((response) => { From 5ccd76bc8c5b070255a11da6ed21e8c4e6cd3c20 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Sat, 14 Oct 2023 17:01:05 +0330 Subject: [PATCH 12/20] CFE-3 testing CreateContent component --- .../PositionAndRole/__tests__/index.test.js | 2 +- .../CreateContent/__tests__/index.test.js | 28 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js index 0e6cf4b..d5c9546 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js @@ -82,7 +82,7 @@ describe("CreateContent Component From Expert Management", () => { }); it('Should Select An Item With Valid Value of role', async () => { render(); - const roleInput = screen.getByTestId("input-role-id") + const roleInput = await waitFor(() => screen.getByTestId("input-role-id")); const roleSelectOpener = await waitFor(() => screen.getByTestId("option-opener-role")); fireEvent.mouseDown(roleSelectOpener); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index cccc604..3c7ca0d 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -6,15 +6,19 @@ import CreateForm from "@/components/dashboard/expert-management/Form/CreateForm describe("CreateContent Component From Expert Management", () => { describe("Rendering", () => { - it("Password TextField Rendered", () => { + it("Password TextField Rendered", async () => { render(); - const cancelBtn = screen.queryByText('بستن'); - expect(cancelBtn).toBeInTheDocument(); + await waitFor(() => { + const cancelBtn = screen.queryByText('بستن'); + expect(cancelBtn).toBeInTheDocument(); + }); }); - it("Password TextField Rendered", () => { + it("Password TextField Rendered", async () => { render(); - const cancelBtn = screen.queryByText('ثبت'); - expect(cancelBtn).toBeInTheDocument(); + await waitFor(() => { + const cancelBtn = screen.queryByText('ثبت'); + expect(cancelBtn).toBeInTheDocument(); + }); }); }); describe("Behavioral", () => { @@ -25,29 +29,35 @@ describe("CreateContent Component From Expert Management", () => { const submitButton = screen.queryByText('ثبت'); - const nameInput = screen.queryByLabelText('نام'); + const nameInput = screen.queryByLabelText('نام کامل'); const usernameInput = screen.queryByLabelText('نام کاربری'); const emailInput = screen.queryByLabelText('پست الکترونیک'); const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + const telephoneIdInput = screen.queryByLabelText('کد تلفن'); const nationalIdInput = screen.queryByLabelText('کد ملی'); const passwordInput = screen.queryByLabelText('رمز عبور'); const positionInput = screen.queryByLabelText('سمت'); const provinceSelectOpener = screen.getByTestId("option-opener-province"); const roleSelectOpener = screen.getByTestId("option-opener-role"); + const genderSelectOpener = screen.getByTestId("option-opener-gender"); fireEvent.mouseDown(provinceSelectOpener); fireEvent.mouseDown(roleSelectOpener); + fireEvent.mouseDown(genderSelectOpener); fireEvent.change(nameInput, {target: {value: 'nameTest'}}); fireEvent.change(usernameInput, {target: {value: 'usernameTest'}}); fireEvent.change(emailInput, {target: {value: 'emailTest'}}); fireEvent.change(phoneNumberInput, {target: {value: 'phoneNumberTest'}}); + fireEvent.change(telephoneIdInput, {target: {value: 'telephoneIdTest'}}); fireEvent.change(nationalIdInput, {target: {value: 'nationalIdTest'}}); fireEvent.change(passwordInput, {target: {value: 'passwordTest'}}); fireEvent.change(positionInput, {target: {value: 'positionTest'}}); - const selectItemProvince = await waitFor(() => screen.queryByText("آذربایجان شرقی")); + const selectItemProvince = screen.queryByText("آذربایجان شرقی"); fireEvent.click(selectItemProvince); - const selectItemRole = await waitFor(() => screen.queryByText("ادمین")); + const selectItemRole = screen.queryByText("ادمین"); fireEvent.click(selectItemRole); + const selectItemGender = screen.queryByText("مرد"); + fireEvent.click(selectItemGender); await waitFor(() => { expect(submitButton).not.toBeDisabled(); From d38b12aa8549d53eeb23cc231481650a23ba8c7c Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 16 Oct 2023 14:11:37 +0330 Subject: [PATCH 13/20] CFE-3 complete Submission part of testing for CreateForm And CreateContent component ubmission part of testing for CreateForm And CreateContent component :q --- mocks/handler.js | 9 +- .../CreateContent/__tests__/index.test.js | 45 +++---- .../Form/CreateForm/__tests__/index.test.js | 112 +++++++++++++++++- .../Form/CreateForm/index.jsx | 2 +- 4 files changed, 143 insertions(+), 25 deletions(-) diff --git a/mocks/handler.js b/mocks/handler.js index a35551c..4ccda1a 100644 --- a/mocks/handler.js +++ b/mocks/handler.js @@ -1,4 +1,4 @@ -import {GET_PROVINCE_LIST, GET_ROLE_LIST, GET_USER_ROUTE} from "@/core/data/apiRoutes"; +import {CREATE_EXPERT_MANAGEMENT, GET_PROVINCE_LIST, GET_ROLE_LIST, GET_USER_ROUTE} from "@/core/data/apiRoutes"; import {rest} from "msw"; export const handler = [ @@ -38,5 +38,10 @@ export const handler = [ } ] })) - }) + }), + rest.post(CREATE_EXPERT_MANAGEMENT, (req, res, ctx) => { + return res( + ctx.status(200), + ); + }), ] \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index 3c7ca0d..02bc549 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -2,7 +2,18 @@ import {fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import CreateContent from "../../CreateContent"; import MockAppWithProviders from "../../../../../../../../mocks/AppWithProvider"; -import CreateForm from "@/components/dashboard/expert-management/Form/CreateForm"; +import userEvent from '@testing-library/user-event'; + +function selectDropdownItem(screen, openerTestId, itemText) { + const opener = screen.getByTestId(openerTestId); + fireEvent.mouseDown(opener); + const selectItem = screen.queryByText(itemText); + fireEvent.click(selectItem); +} + +function setInputValue(screen, inputElement, value) { + fireEvent.change(inputElement, {target: {value}}); +} describe("CreateContent Component From Expert Management", () => { describe("Rendering", () => { @@ -37,27 +48,19 @@ describe("CreateContent Component From Expert Management", () => { const nationalIdInput = screen.queryByLabelText('کد ملی'); const passwordInput = screen.queryByLabelText('رمز عبور'); const positionInput = screen.queryByLabelText('سمت'); - const provinceSelectOpener = screen.getByTestId("option-opener-province"); - const roleSelectOpener = screen.getByTestId("option-opener-role"); - const genderSelectOpener = screen.getByTestId("option-opener-gender"); - fireEvent.mouseDown(provinceSelectOpener); - fireEvent.mouseDown(roleSelectOpener); - fireEvent.mouseDown(genderSelectOpener); - fireEvent.change(nameInput, {target: {value: 'nameTest'}}); - fireEvent.change(usernameInput, {target: {value: 'usernameTest'}}); - fireEvent.change(emailInput, {target: {value: 'emailTest'}}); - fireEvent.change(phoneNumberInput, {target: {value: 'phoneNumberTest'}}); - fireEvent.change(telephoneIdInput, {target: {value: 'telephoneIdTest'}}); - fireEvent.change(nationalIdInput, {target: {value: 'nationalIdTest'}}); - fireEvent.change(passwordInput, {target: {value: 'passwordTest'}}); - fireEvent.change(positionInput, {target: {value: 'positionTest'}}); - const selectItemProvince = screen.queryByText("آذربایجان شرقی"); - fireEvent.click(selectItemProvince); - const selectItemRole = screen.queryByText("ادمین"); - fireEvent.click(selectItemRole); - const selectItemGender = screen.queryByText("مرد"); - fireEvent.click(selectItemGender); + selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); + selectDropdownItem(screen, "option-opener-role", "ادمین"); + selectDropdownItem(screen, "option-opener-gender", "مرد"); + + setInputValue(screen, nameInput, 'nameTest'); + setInputValue(screen, usernameInput, 'usernameTest'); + setInputValue(screen, emailInput, 'emailTest'); + setInputValue(screen, phoneNumberInput, 'phoneNumberTest'); + setInputValue(screen, telephoneIdInput, 'telephoneIdTest'); + setInputValue(screen, nationalIdInput, 'nationalIdTest'); + setInputValue(screen, passwordInput, 'passwordTest'); + setInputValue(screen, positionInput, 'positionTest'); await waitFor(() => { expect(submitButton).not.toBeDisabled(); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js index 1e85160..cab2609 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js @@ -1,8 +1,19 @@ -import {act, fireEvent, render, screen} from "@testing-library/react"; +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import MockAppWithProviders from "../../../../../../../mocks/AppWithProvider"; import CreateForm from "../../CreateForm"; +function selectDropdownItem(screen, openerTestId, itemText) { + const opener = screen.getByTestId(openerTestId); + fireEvent.mouseDown(opener); + const selectItem = screen.queryByText(itemText); + fireEvent.click(selectItem); +} + +function setInputValue(screen, inputElement, value) { + fireEvent.change(inputElement, {target: {value}}); +} + describe("CreateForm Component From Expert Management", () => { describe("Rendering", () => { it("Create Button Rendered", () => { @@ -27,4 +38,103 @@ describe("CreateForm Component From Expert Management", () => { }); }); }); + describe("Form Submission", () => { + it('Should request to api and if get success close dialog', async () => { + render(); + + const CreateButton = screen.getByRole('button', {name: "افزودن کارشناس"}); + fireEvent.click(CreateButton); + + const submitButton = screen.queryByText('ثبت'); + + const nameInput = screen.queryByLabelText('نام کامل'); + const usernameInput = screen.queryByLabelText('نام کاربری'); + const emailInput = screen.queryByLabelText('پست الکترونیک'); + const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + const telephoneIdInput = screen.queryByLabelText('کد تلفن'); + const nationalIdInput = screen.queryByLabelText('کد ملی'); + const passwordInput = screen.queryByLabelText('رمز عبور'); + const positionInput = screen.queryByLabelText('سمت'); + + selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); + selectDropdownItem(screen, "option-opener-role", "ادمین"); + selectDropdownItem(screen, "option-opener-gender", "مرد"); + + setInputValue(screen, nameInput, 'nameTest'); + setInputValue(screen, usernameInput, 'usernameTest'); + setInputValue(screen, emailInput, 'emailTest@gmail.com'); + setInputValue(screen, phoneNumberInput, '0914577458'); + setInputValue(screen, telephoneIdInput, '091'); + setInputValue(screen, nationalIdInput, 'nationalIdTest'); + setInputValue(screen, passwordInput, 'passwordTest12'); + setInputValue(screen, positionInput, 'positionTest'); + + expect(submitButton).not.toBeDisabled(); + await fireEvent.click(submitButton); + + await waitFor(() => { + const dialogContent = screen.getByTestId('create-dialog-content'); + expect(dialogContent).not.toBeInTheDocument(); + }); + }); + it('Should request to api and if get error keep previous data', async () => { + render(); + + const CreateButton = screen.getByRole('button', {name: "افزودن کارشناس"}); + fireEvent.click(CreateButton); + + const submitButton = screen.queryByText('ثبت'); + + const nameInput = screen.queryByLabelText('نام کامل'); + const usernameInput = screen.queryByLabelText('نام کاربری'); + const emailInput = screen.queryByLabelText('پست الکترونیک'); + const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + const telephoneIdInput = screen.queryByLabelText('کد تلفن'); + const nationalIdInput = screen.queryByLabelText('کد ملی'); + const passwordInput = screen.queryByLabelText('رمز عبور'); + const positionInput = screen.queryByLabelText('سمت'); + const provinceSelectOpener = screen.getByTestId("option-opener-province"); + const provinceInput = screen.getByTestId("input-province-id") + const roleSelectOpener = screen.getByTestId("option-opener-role"); + const roleInput = screen.getByTestId("input-role-id") + const genderSelectOpener = screen.getByTestId("option-opener-gender"); + const genderInput = screen.getByTestId("input-gender") + fireEvent.mouseDown(provinceSelectOpener); + fireEvent.mouseDown(roleSelectOpener); + fireEvent.mouseDown(genderSelectOpener); + + fireEvent.change(nameInput, {target: {value: 'nameTest'}}); + fireEvent.change(usernameInput, {target: {value: 'usernameTest'}}); + fireEvent.change(emailInput, {target: {value: 'emailTest'}}); + fireEvent.change(phoneNumberInput, {target: {value: 'phoneNumberTest'}}); + fireEvent.change(telephoneIdInput, {target: {value: 'telephoneIdTest'}}); + fireEvent.change(nationalIdInput, {target: {value: 'nationalIdTest'}}); + fireEvent.change(passwordInput, {target: {value: 'passwordTest'}}); + fireEvent.change(positionInput, {target: {value: 'positionTest'}}); + const selectItemProvince = screen.queryByText("آذربایجان شرقی"); + fireEvent.click(selectItemProvince); + const selectItemRole = screen.queryByText("ادمین"); + fireEvent.click(selectItemRole); + const selectItemGender = screen.queryByText("مرد"); + fireEvent.click(selectItemGender); + + expect(submitButton).not.toBeDisabled(); + await fireEvent.click(submitButton); + + await waitFor(() => { + expect(nameInput).toHaveValue('nameTest'); + expect(usernameInput).toHaveValue('usernameTest'); + expect(emailInput).toHaveValue('emailTest'); + expect(phoneNumberInput).toHaveValue('phoneNumberTest'); + expect(telephoneIdInput).toHaveValue('telephoneIdTest'); + expect(nationalIdInput).toHaveValue('nationalIdTest'); + expect(passwordInput).toHaveValue('passwordTest'); + expect(positionInput).toHaveValue('positionTest'); + expect(provinceInput).toHaveValue('1'); + expect(roleInput).toHaveValue('1'); + expect(genderInput).toHaveValue('male'); + + }); + }); + }) }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/index.jsx index 4b732aa..e50bc7e 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/index.jsx @@ -26,7 +26,7 @@ const Create = ({mutate, fetchUrl}) => { - {t("ExpertMangement.create")} From e9795d5935c6d033e281d84cd3bcdf3d460b3880 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Mon, 16 Oct 2023 15:55:55 +0330 Subject: [PATCH 14/20] CFE-3 CreateForm Component Debug Tests And Delete Expert Complete With its Own Tests --- mocks/handler.js | 10 +- public/locales/fa/app.json | 6 +- .../expert-management/DataTable/index.jsx | 4 +- .../Form/CreateForm/CreateContent/index.jsx | 4 +- .../Form/CreateForm/__tests__/index.test.js | 118 ++++++++---------- .../Form/DeleteForm/__tests__/index.test.js | 53 ++++++++ .../Form/DeleteForm/index.jsx | 79 +++++++++++- .../expert-management/TableRowActions.jsx | 10 +- src/core/data/apiRoutes.js | 3 +- 9 files changed, 204 insertions(+), 83 deletions(-) create mode 100644 src/components/dashboard/expert-management/Form/DeleteForm/__tests__/index.test.js diff --git a/mocks/handler.js b/mocks/handler.js index 4ccda1a..96190e5 100644 --- a/mocks/handler.js +++ b/mocks/handler.js @@ -1,4 +1,10 @@ -import {CREATE_EXPERT_MANAGEMENT, GET_PROVINCE_LIST, GET_ROLE_LIST, GET_USER_ROUTE} from "@/core/data/apiRoutes"; +import { + CREATE_EXPERT_MANAGEMENT, + EXPERT_MANAGEMENT, + GET_PROVINCE_LIST, + GET_ROLE_LIST, + GET_USER_ROUTE +} from "@/core/data/apiRoutes"; import {rest} from "msw"; export const handler = [ @@ -39,7 +45,7 @@ export const handler = [ ] })) }), - rest.post(CREATE_EXPERT_MANAGEMENT, (req, res, ctx) => { + rest.post(EXPERT_MANAGEMENT, (req, res, ctx) => { return res( ctx.status(200), ); diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 54d5622..89efd13 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -170,6 +170,10 @@ "error_message_new_password": "رمز عبور جدید را وارد کنید", "error_message_new_password_regex": "رمز عبور باید حداقل 8 کاراکتر و متشکل از عدد، حرف یا سمبل باشد", "button_cancel": "بستن", - "button_confirm": "ثبت" + "button_confirm": "ثبت", + "delete_expert": "حذف کارشناس", + "are_you_sure_text": "آیا از انجام این عملیات اطمینان دارید؟", + "button_delete": "حذف", + "delete_tooltip": "حذف" } } diff --git a/src/components/dashboard/expert-management/DataTable/index.jsx b/src/components/dashboard/expert-management/DataTable/index.jsx index b3b4564..697fab1 100644 --- a/src/components/dashboard/expert-management/DataTable/index.jsx +++ b/src/components/dashboard/expert-management/DataTable/index.jsx @@ -1,6 +1,6 @@ import DataTable from "@/core/components/DataTable"; import MuiDatePicker from "@/core/components/MuiDatePicker"; -import {GET_EXPERT_MANAGEMENT_LIST} from "@/core/data/apiRoutes"; +import {EXPERT_MANAGEMENT} from "@/core/data/apiRoutes"; import TableToolbar from "../TableToolbar"; import TableRowActions from "../TableRowActions"; import {Box, Typography} from "@mui/material"; @@ -152,7 +152,7 @@ function ExpertManagementDataTable() { return ( { formData.append("position", values.position); formData.append("roles", values.roles); - requestServer(`${CREATE_EXPERT_MANAGEMENT}`, 'post', {auth: true, data: formData}) + requestServer(`${EXPERT_MANAGEMENT}`, 'post', {auth: true, data: formData}) .then((response) => { mutate(fetchUrl) setOpenCreateDialog(false) diff --git a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js index cab2609..f347376 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js @@ -39,44 +39,45 @@ describe("CreateForm Component From Expert Management", () => { }); }); describe("Form Submission", () => { - it('Should request to api and if get success close dialog', async () => { - render(); - - const CreateButton = screen.getByRole('button', {name: "افزودن کارشناس"}); - fireEvent.click(CreateButton); - - const submitButton = screen.queryByText('ثبت'); - - const nameInput = screen.queryByLabelText('نام کامل'); - const usernameInput = screen.queryByLabelText('نام کاربری'); - const emailInput = screen.queryByLabelText('پست الکترونیک'); - const phoneNumberInput = screen.queryByLabelText('شماره همراه'); - const telephoneIdInput = screen.queryByLabelText('کد تلفن'); - const nationalIdInput = screen.queryByLabelText('کد ملی'); - const passwordInput = screen.queryByLabelText('رمز عبور'); - const positionInput = screen.queryByLabelText('سمت'); - - selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); - selectDropdownItem(screen, "option-opener-role", "ادمین"); - selectDropdownItem(screen, "option-opener-gender", "مرد"); - - setInputValue(screen, nameInput, 'nameTest'); - setInputValue(screen, usernameInput, 'usernameTest'); - setInputValue(screen, emailInput, 'emailTest@gmail.com'); - setInputValue(screen, phoneNumberInput, '0914577458'); - setInputValue(screen, telephoneIdInput, '091'); - setInputValue(screen, nationalIdInput, 'nationalIdTest'); - setInputValue(screen, passwordInput, 'passwordTest12'); - setInputValue(screen, positionInput, 'positionTest'); - - expect(submitButton).not.toBeDisabled(); - await fireEvent.click(submitButton); - - await waitFor(() => { - const dialogContent = screen.getByTestId('create-dialog-content'); - expect(dialogContent).not.toBeInTheDocument(); - }); - }); + // ask about this part + // it('Should request to api and if get success close dialog', async () => { + // render(); + // + // const CreateButton = screen.getByRole('button', {name: "افزودن کارشناس"}); + // fireEvent.click(CreateButton); + // + // const submitButton = screen.queryByText('ثبت'); + // + // const nameInput = screen.queryByLabelText('نام کامل'); + // const usernameInput = screen.queryByLabelText('نام کاربری'); + // const emailInput = screen.queryByLabelText('پست الکترونیک'); + // const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + // const telephoneIdInput = screen.queryByLabelText('کد تلفن'); + // const nationalIdInput = screen.queryByLabelText('کد ملی'); + // const passwordInput = screen.queryByLabelText('رمز عبور'); + // const positionInput = screen.queryByLabelText('سمت'); + // + // selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); + // selectDropdownItem(screen, "option-opener-role", "ادمین"); + // selectDropdownItem(screen, "option-opener-gender", "مرد"); + // + // setInputValue(screen, nameInput, 'nameTest'); + // setInputValue(screen, usernameInput, 'usernameTest'); + // setInputValue(screen, emailInput, 'emailTest@gmail.com'); + // setInputValue(screen, phoneNumberInput, '0914577458'); + // setInputValue(screen, telephoneIdInput, '091'); + // setInputValue(screen, nationalIdInput, 'nationalIdTest'); + // setInputValue(screen, passwordInput, 'passwordTest12'); + // setInputValue(screen, positionInput, 'positionTest'); + // + // expect(submitButton).not.toBeDisabled(); + // await fireEvent.click(submitButton); + // + // await waitFor(() => { + // const dialogContent = screen.getByTestId('create-dialog-content'); + // expect(dialogContent).not.toBeInTheDocument(); + // }); + // }); it('Should request to api and if get error keep previous data', async () => { render(); @@ -93,30 +94,22 @@ describe("CreateForm Component From Expert Management", () => { const nationalIdInput = screen.queryByLabelText('کد ملی'); const passwordInput = screen.queryByLabelText('رمز عبور'); const positionInput = screen.queryByLabelText('سمت'); - const provinceSelectOpener = screen.getByTestId("option-opener-province"); const provinceInput = screen.getByTestId("input-province-id") - const roleSelectOpener = screen.getByTestId("option-opener-role"); const roleInput = screen.getByTestId("input-role-id") - const genderSelectOpener = screen.getByTestId("option-opener-gender"); const genderInput = screen.getByTestId("input-gender") - fireEvent.mouseDown(provinceSelectOpener); - fireEvent.mouseDown(roleSelectOpener); - fireEvent.mouseDown(genderSelectOpener); - fireEvent.change(nameInput, {target: {value: 'nameTest'}}); - fireEvent.change(usernameInput, {target: {value: 'usernameTest'}}); - fireEvent.change(emailInput, {target: {value: 'emailTest'}}); - fireEvent.change(phoneNumberInput, {target: {value: 'phoneNumberTest'}}); - fireEvent.change(telephoneIdInput, {target: {value: 'telephoneIdTest'}}); - fireEvent.change(nationalIdInput, {target: {value: 'nationalIdTest'}}); - fireEvent.change(passwordInput, {target: {value: 'passwordTest'}}); - fireEvent.change(positionInput, {target: {value: 'positionTest'}}); - const selectItemProvince = screen.queryByText("آذربایجان شرقی"); - fireEvent.click(selectItemProvince); - const selectItemRole = screen.queryByText("ادمین"); - fireEvent.click(selectItemRole); - const selectItemGender = screen.queryByText("مرد"); - fireEvent.click(selectItemGender); + selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); + selectDropdownItem(screen, "option-opener-role", "ادمین"); + selectDropdownItem(screen, "option-opener-gender", "مرد"); + + setInputValue(screen, nameInput, 'nameTest'); + setInputValue(screen, usernameInput, 'usernameTest'); + setInputValue(screen, emailInput, 'emailTest@gmail.com'); + setInputValue(screen, phoneNumberInput, '0914577458'); + setInputValue(screen, telephoneIdInput, '091'); + setInputValue(screen, nationalIdInput, 'nationalIdTest'); + setInputValue(screen, passwordInput, 'passwordTest12'); + setInputValue(screen, positionInput, 'positionTest'); expect(submitButton).not.toBeDisabled(); await fireEvent.click(submitButton); @@ -124,16 +117,15 @@ describe("CreateForm Component From Expert Management", () => { await waitFor(() => { expect(nameInput).toHaveValue('nameTest'); expect(usernameInput).toHaveValue('usernameTest'); - expect(emailInput).toHaveValue('emailTest'); - expect(phoneNumberInput).toHaveValue('phoneNumberTest'); - expect(telephoneIdInput).toHaveValue('telephoneIdTest'); + expect(emailInput).toHaveValue('emailTest@gmail.com'); + expect(phoneNumberInput).toHaveValue('0914577458'); + expect(telephoneIdInput).toHaveValue('091'); expect(nationalIdInput).toHaveValue('nationalIdTest'); - expect(passwordInput).toHaveValue('passwordTest'); + expect(passwordInput).toHaveValue('passwordTest12'); expect(positionInput).toHaveValue('positionTest'); expect(provinceInput).toHaveValue('1'); expect(roleInput).toHaveValue('1'); expect(genderInput).toHaveValue('male'); - }); }); }) diff --git a/src/components/dashboard/expert-management/Form/DeleteForm/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/DeleteForm/__tests__/index.test.js new file mode 100644 index 0000000..df11883 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/DeleteForm/__tests__/index.test.js @@ -0,0 +1,53 @@ +import {act, fireEvent, render, screen} from "@testing-library/react"; +import MockAppWithProviders from "../../../../../../../mocks/AppWithProvider"; +import React from "react"; +import DeleteForm from "@/components/dashboard/expert-management/Form/DeleteForm"; + +describe("CreateForm Component From Expert Management", () => { + describe("Rendering", () => { + it("Delete Expert Button And Tooltip Rendered", () => { + render(); + const DeleteButton = screen.getByTestId('delete-button'); + expect(DeleteButton).toBeInTheDocument(); + }); + it("Delete Dialog Rendered", () => { + render(); + const DeleteButton = screen.getByTestId('delete-button'); + fireEvent.click(DeleteButton); + const DeleteDialogHeader = screen.queryByText("حذف کارشناس"); + expect(DeleteDialogHeader).toBeInTheDocument(); + }); + it("Delete Dialog Text Rendered", () => { + render(); + const DeleteButton = screen.getByTestId('delete-button'); + fireEvent.click(DeleteButton); + const DeleteDialogText = screen.queryByText("آیا از انجام این عملیات اطمینان دارید؟"); + expect(DeleteDialogText).toBeInTheDocument(); + }); + it("Delete Dialog Delete Button Rendered", () => { + render(); + const DeleteButton = screen.getByTestId('delete-button'); + fireEvent.click(DeleteButton); + const DeleteButtonDialog = screen.getByRole('button', {name: "حذف"}); + expect(DeleteButtonDialog).toBeInTheDocument(); + }); + it("Delete Dialog Cancel Button Rendered", () => { + render(); + const DeleteButton = screen.getByTestId('delete-button'); + fireEvent.click(DeleteButton); + const CancelButtonDialog = screen.getByRole('button', {name: "بستن"}); + expect(CancelButtonDialog).toBeInTheDocument(); + }); + }); + describe("Behavioral", () => { + it("By Clicking Delete Button Dialog Should Append To Document", async () => { + render(); + const DeleteButton = screen.getByTestId('delete-button'); + fireEvent.click(DeleteButton); + await act(() => { + const DeleteDialog = screen.getByRole('dialog', {name: "حذف کارشناس"}) + expect(DeleteDialog).toBeInTheDocument(); + }); + }); + }); +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx b/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx index 11320cc..ed60083 100644 --- a/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx +++ b/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx @@ -1,7 +1,74 @@ -const Delete = () => { - return ( - <> - ) -} +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + IconButton, + Tooltip +} from "@mui/material"; +import DeleteIcon from '@mui/icons-material/Delete'; +import {useState} from "react"; +import {EXPERT_MANAGEMENT} from "@/core/data/apiRoutes"; +import useRequest from "@/lib/app/hooks/useRequest"; +import {useTranslations} from "next-intl"; -export default Delete \ No newline at end of file +const Delete = ({rowId, fetchUrl, mutate}) => { + const t = useTranslations(); + const requestServer = useRequest({auth: true}); + const [openDeleteDialog, setOpenDeleteDialog] = useState(false); + const [isSubmitting, setIsSubmitting] = useState(false); + + const handleDelete = () => { + setIsSubmitting(true) + requestServer(`${EXPERT_MANAGEMENT}/${rowId}`, 'DELETE') + .then((response) => { + mutate(fetchUrl) + }) + .catch(() => { + }) + .finally(() => { + setIsSubmitting(false) + setOpenDeleteDialog(false); + }); + }; + + return ( + <> + + { + setOpenDeleteDialog(true); + }} + > + + + + + {t("ExpertMangement.delete_expert")} + + {t("ExpertMangement.are_you_sure_text")} + + + + + + + + ); +}; +export default Delete; \ No newline at end of file diff --git a/src/components/dashboard/expert-management/TableRowActions.jsx b/src/components/dashboard/expert-management/TableRowActions.jsx index 19830ce..1b0eff5 100644 --- a/src/components/dashboard/expert-management/TableRowActions.jsx +++ b/src/components/dashboard/expert-management/TableRowActions.jsx @@ -11,11 +11,11 @@ const TableRowActions = ({row, mutate, fetchUrl}) => { mutate={mutate} fetchUrl={fetchUrl} /> - + {/**/} Date: Tue, 17 Oct 2023 11:15:59 +0330 Subject: [PATCH 15/20] DeleteForm Complete With Tests of It Rendering/Beahavioral/submission --- mocks/handler.js | 5 ++ .../CreateContent/__tests__/index.test.js | 1 + .../Form/CreateForm/CreateContent/index.jsx | 2 +- .../Form/CreateForm/__tests__/index.test.js | 77 +++++++++---------- .../Form/DeleteForm/__tests__/index.test.js | 17 +++- .../Form/DeleteForm/index.jsx | 2 +- 6 files changed, 61 insertions(+), 43 deletions(-) diff --git a/mocks/handler.js b/mocks/handler.js index 96190e5..dfac7e8 100644 --- a/mocks/handler.js +++ b/mocks/handler.js @@ -50,4 +50,9 @@ export const handler = [ ctx.status(200), ); }), + rest.delete(`${EXPERT_MANAGEMENT}/:id`, (req, res, ctx) => { + return res( + ctx.status(200), + ); + }), ] \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index 02bc549..1e71174 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -3,6 +3,7 @@ import React from 'react'; import CreateContent from "../../CreateContent"; import MockAppWithProviders from "../../../../../../../../mocks/AppWithProvider"; import userEvent from '@testing-library/user-event'; +import CreateForm from "@/components/dashboard/expert-management/Form/CreateForm"; function selectDropdownItem(screen, openerTestId, itemText) { const opener = screen.getByTestId(openerTestId); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx index 6144e85..acac74c 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/index.jsx @@ -62,8 +62,8 @@ const CreateContent = ({setOpenCreateDialog, mutate, fetchUrl}) => { requestServer(`${EXPERT_MANAGEMENT}`, 'post', {auth: true, data: formData}) .then((response) => { - mutate(fetchUrl) setOpenCreateDialog(false) + mutate(fetchUrl) }).catch(() => { }).finally(() => { setSubmitting(false); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js index f347376..8bf825d 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/__tests__/index.test.js @@ -39,45 +39,44 @@ describe("CreateForm Component From Expert Management", () => { }); }); describe("Form Submission", () => { - // ask about this part - // it('Should request to api and if get success close dialog', async () => { - // render(); - // - // const CreateButton = screen.getByRole('button', {name: "افزودن کارشناس"}); - // fireEvent.click(CreateButton); - // - // const submitButton = screen.queryByText('ثبت'); - // - // const nameInput = screen.queryByLabelText('نام کامل'); - // const usernameInput = screen.queryByLabelText('نام کاربری'); - // const emailInput = screen.queryByLabelText('پست الکترونیک'); - // const phoneNumberInput = screen.queryByLabelText('شماره همراه'); - // const telephoneIdInput = screen.queryByLabelText('کد تلفن'); - // const nationalIdInput = screen.queryByLabelText('کد ملی'); - // const passwordInput = screen.queryByLabelText('رمز عبور'); - // const positionInput = screen.queryByLabelText('سمت'); - // - // selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); - // selectDropdownItem(screen, "option-opener-role", "ادمین"); - // selectDropdownItem(screen, "option-opener-gender", "مرد"); - // - // setInputValue(screen, nameInput, 'nameTest'); - // setInputValue(screen, usernameInput, 'usernameTest'); - // setInputValue(screen, emailInput, 'emailTest@gmail.com'); - // setInputValue(screen, phoneNumberInput, '0914577458'); - // setInputValue(screen, telephoneIdInput, '091'); - // setInputValue(screen, nationalIdInput, 'nationalIdTest'); - // setInputValue(screen, passwordInput, 'passwordTest12'); - // setInputValue(screen, positionInput, 'positionTest'); - // - // expect(submitButton).not.toBeDisabled(); - // await fireEvent.click(submitButton); - // - // await waitFor(() => { - // const dialogContent = screen.getByTestId('create-dialog-content'); - // expect(dialogContent).not.toBeInTheDocument(); - // }); - // }); + it('Should request to api and if get success close dialog', async () => { + render(); + + const CreateButton = screen.getByRole('button', {name: "افزودن کارشناس"}); + fireEvent.click(CreateButton); + + const submitButton = screen.queryByText('ثبت'); + + const nameInput = screen.queryByLabelText('نام کامل'); + const usernameInput = screen.queryByLabelText('نام کاربری'); + const emailInput = screen.queryByLabelText('پست الکترونیک'); + const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + const telephoneIdInput = screen.queryByLabelText('کد تلفن'); + const nationalIdInput = screen.queryByLabelText('کد ملی'); + const passwordInput = screen.queryByLabelText('رمز عبور'); + const positionInput = screen.queryByLabelText('سمت'); + + selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); + selectDropdownItem(screen, "option-opener-role", "ادمین"); + selectDropdownItem(screen, "option-opener-gender", "مرد"); + + setInputValue(screen, nameInput, 'nameTest'); + setInputValue(screen, usernameInput, 'usernameTest'); + setInputValue(screen, emailInput, 'emailTest@gmail.com'); + setInputValue(screen, phoneNumberInput, '0914577458'); + setInputValue(screen, telephoneIdInput, '091'); + setInputValue(screen, nationalIdInput, 'nationalIdTest'); + setInputValue(screen, passwordInput, 'passwordTest12'); + setInputValue(screen, positionInput, 'positionTest'); + + expect(submitButton).not.toBeDisabled(); + fireEvent.click(submitButton); + + await waitFor(() => { + const dialogContent = screen.queryByTestId('create-dialog-content'); + expect(dialogContent).not.toBeInTheDocument(); + }); + }); it('Should request to api and if get error keep previous data', async () => { render(); diff --git a/src/components/dashboard/expert-management/Form/DeleteForm/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/DeleteForm/__tests__/index.test.js index df11883..f2e52b0 100644 --- a/src/components/dashboard/expert-management/Form/DeleteForm/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/DeleteForm/__tests__/index.test.js @@ -1,4 +1,4 @@ -import {act, fireEvent, render, screen} from "@testing-library/react"; +import {fireEvent, render, screen, waitFor} from "@testing-library/react"; import MockAppWithProviders from "../../../../../../../mocks/AppWithProvider"; import React from "react"; import DeleteForm from "@/components/dashboard/expert-management/Form/DeleteForm"; @@ -44,10 +44,23 @@ describe("CreateForm Component From Expert Management", () => { render(); const DeleteButton = screen.getByTestId('delete-button'); fireEvent.click(DeleteButton); - await act(() => { + await waitFor(() => { const DeleteDialog = screen.getByRole('dialog', {name: "حذف کارشناس"}) expect(DeleteDialog).toBeInTheDocument(); }); }); }); + describe("Form Submission", () => { + it("By Clicking Delete Button Request To Api And Delete Item", async () => { + render(); + const DeleteButton = screen.getByTestId('delete-button'); + fireEvent.click(DeleteButton); + const DeleteButtonDialog = screen.getByRole('button', {name: "حذف"}); + fireEvent.click(DeleteButtonDialog); + await waitFor(() => { + const DeleteDialog = screen.queryByRole('dialog', {name: "حذف کارشناس"}); + expect(DeleteDialog).not.toBeInTheDocument(); + }); + }); + }); }); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx b/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx index ed60083..03a9e82 100644 --- a/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx +++ b/src/components/dashboard/expert-management/Form/DeleteForm/index.jsx @@ -24,13 +24,13 @@ const Delete = ({rowId, fetchUrl, mutate}) => { setIsSubmitting(true) requestServer(`${EXPERT_MANAGEMENT}/${rowId}`, 'DELETE') .then((response) => { + setOpenDeleteDialog(false); mutate(fetchUrl) }) .catch(() => { }) .finally(() => { setIsSubmitting(false) - setOpenDeleteDialog(false); }); }; From 8c2ad759b0f0876b7418ecc0e2c1ea2892afd085 Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Wed, 18 Oct 2023 11:15:00 +0330 Subject: [PATCH 16/20] complete UpdateForm component and all of its sub items with their own tests and add gitlab-ci and new eslint file --- .gitlab-ci.yml | 118 ++++++++++ mocks/handler.js | 5 + public/locales/fa/app.json | 4 +- .../PersonalInfo/__tests__/index.test.js | 2 +- .../PositionAndRole/__tests__/index.test.js | 5 +- .../RestInfo/Province/__tests__/index.test.js | 4 +- .../CreateContent/RestInfo/Province/index.jsx | 1 - .../UserInfo/__test__/index.test.js | 5 +- .../CreateContent/__tests__/index.test.js | 10 +- .../PersonalInfo/__tests__/index.test.js | 219 ++++++++++++++++++ .../UpdateContent/PersonalInfo/index.jsx | 128 ++++++++++ .../RestInfo/PositionAndRole/Index.jsx | 75 ++++++ .../PositionAndRole/__tests__/index.test.js | 96 ++++++++ .../RestInfo/Province/__tests__/index.test.js | 71 ++++++ .../UpdateContent/RestInfo/Province/index.jsx | 61 +++++ .../UpdateContent/RestInfo/index.jsx | 12 + .../UserInfo/__tests__/index.test.js | 62 +++++ .../UpdateContent/UserInfo/index.jsx | 29 +++ .../UpdateContent/__tests__/index.test.js | 87 +++++++ .../Form/UpdateForm/UpdateContent/index.jsx | 108 +++++++++ .../Form/UpdateForm/__tests__/index.test.js | 147 ++++++++++++ .../Form/UpdateForm/index.jsx | 38 ++- src/lib/app/hooks/useProvince.jsx | 3 +- src/lib/app/hooks/useRole.jsx | 3 +- 24 files changed, 1266 insertions(+), 27 deletions(-) create mode 100644 .gitlab-ci.yml create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/PersonalInfo/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/PersonalInfo/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/Index.jsx create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/UserInfo/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/UserInfo/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/__tests__/index.test.js create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/index.jsx create mode 100644 src/components/dashboard/expert-management/Form/UpdateForm/__tests__/index.test.js diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..27bf1b1 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,118 @@ +image: node:latest + +stages: + - build + - test + - test:build + - deploy + +merge:build: + stage: build + script: + - npm install + - cp example.env.local .env.local + - cp example.env.local .env.test + only: + - merge_requests + artifacts: + paths: + - node_modules + - .env.local + - .env.test + +merge:test:jest: + stage: test + script: + - npm run test + only: + - merge_requests + artifacts: + paths: + - node_modules + - .env.local + - .env.test + +merge:test:lint: + stage: test + script: + - npm run lint + only: + - merge_requests + artifacts: + paths: + - node_modules + - .env.local + - .env.test + +merge:test:build: + stage: test:build + script: + - npm run build + only: + - merge_requests + artifacts: + paths: + - node_modules + - .env.local + - .env.test + +build: + stage: build + script: + - npm install + - cp example.env.local .env.local + - cp example.env.local .env.test + only: + - develop + - main + artifacts: + paths: + - node_modules + - .env.local + - .env.test + +test:jest: + stage: test + script: + - npm run test + only: + - develop + - main + artifacts: + paths: + - node_modules + - .env.local + - .env.test + +test:lint: + stage: test + script: + - npm run lint + only: + - develop + - main + artifacts: + paths: + - node_modules + - .env.local + - .env.test + +test:build: + stage: test:build + script: + - npm run build + only: + - develop + - main + artifacts: + paths: + - node_modules + - .env.local + - .env.test + +deploy: + stage: deploy + script: + - echo "Run deploy project" + only: + - main \ No newline at end of file diff --git a/mocks/handler.js b/mocks/handler.js index dfac7e8..da1bc4e 100644 --- a/mocks/handler.js +++ b/mocks/handler.js @@ -55,4 +55,9 @@ export const handler = [ ctx.status(200), ); }), + rest.post(`${EXPERT_MANAGEMENT}/:id`, (req, res, ctx) => { + return res( + ctx.status(200), + ); + }), ] \ No newline at end of file diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 89efd13..3774d17 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -174,6 +174,8 @@ "delete_expert": "حذف کارشناس", "are_you_sure_text": "آیا از انجام این عملیات اطمینان دارید؟", "button_delete": "حذف", - "delete_tooltip": "حذف" + "delete_tooltip": "حذف", + "update_tooltip": "ویرایش", + "update_expert": "ویرایش کارشناس" } } diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js index 0f79edd..913c37a 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo/__tests__/index.test.js @@ -38,7 +38,7 @@ const CreateFormMock = ({Component}) => { }; -describe("PersonalInfo Component From Expert Management", () => { +describe("PersonalInfo Component From Expert Management (create)", () => { describe("Rendering", () => { it("full_name TextField Rendered", async () => { render(); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js index d5c9546..6f32bac 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole/__tests__/index.test.js @@ -1,11 +1,10 @@ -import {act, findByRole, findByText, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import {fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import {useTranslations} from "next-intl"; import * as Yup from "yup"; import {Formik} from "formik"; import MockAppWithProviders from "../../../../../../../../../../mocks/AppWithProvider"; import PositionAndRole from "../../PositionAndRole"; -import {MenuItem, Select} from "@mui/material"; const CreateFormMock = ({Component}) => { const t = useTranslations(); @@ -28,7 +27,7 @@ const CreateFormMock = ({Component}) => { ); }; -describe("CreateContent Component From Expert Management", () => { +describe("PositionAndRole Component From Expert Management (create)", () => { describe("Rendering", () => { it("Position TextField Rendered", async () => { render(); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js index 354df01..87da19f 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/__tests__/index.test.js @@ -5,8 +5,6 @@ import * as Yup from "yup"; import {Formik} from "formik"; import Province from "../../Province"; import MockAppWithProviders from "../../../../../../../../../../mocks/AppWithProvider"; -import PositionAndRole - from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/PositionAndRole"; const CreateFormMock = ({Component}) => { const t = useTranslations(); @@ -27,7 +25,7 @@ const CreateFormMock = ({Component}) => { ); }; -describe("CreateContent Component From Expert Management", () => { +describe("Province Component From Expert Management (create)", () => { describe("Rendering", () => { it("Province Select Box Rendered", async () => { render(); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx index 4c8995c..5ac94b2 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province/index.jsx @@ -1,6 +1,5 @@ import {FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select} from "@mui/material"; import {useTranslations} from "next-intl"; -import {useState} from "react"; import useProvince from "@/lib/app/hooks/useProvince"; import useRequest from "@/lib/app/hooks/useRequest"; diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js index 7f10a99..519cf9d 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/UserInfo/__test__/index.test.js @@ -5,7 +5,6 @@ import {useTranslations} from "next-intl"; import * as Yup from "yup"; import {Formik} from "formik"; import UserInfo from "../../UserInfo"; -import PersonalInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo"; const CreateFormMock = ({Component}) => { const t = useTranslations(); @@ -33,7 +32,7 @@ const CreateFormMock = ({Component}) => { ); }; -describe("CreateContent Component From Expert Management", () => { +describe("UserInfo Component From Expert Management (create)", () => { describe("Rendering", () => { it("UserName TextField Rendered", async () => { render(); @@ -98,7 +97,7 @@ describe("CreateContent Component From Expert Management", () => { render(); const passwordInput = screen.queryByLabelText('رمز عبور'); - + // check without text or symbol fireEvent.change(passwordInput, {target: {value: '12345678'}}); fireEvent.blur(passwordInput); diff --git a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js index 1e71174..85751c5 100644 --- a/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/Form/CreateForm/CreateContent/__tests__/index.test.js @@ -2,8 +2,6 @@ import {fireEvent, render, screen, waitFor} from "@testing-library/react"; import React from 'react'; import CreateContent from "../../CreateContent"; import MockAppWithProviders from "../../../../../../../../mocks/AppWithProvider"; -import userEvent from '@testing-library/user-event'; -import CreateForm from "@/components/dashboard/expert-management/Form/CreateForm"; function selectDropdownItem(screen, openerTestId, itemText) { const opener = screen.getByTestId(openerTestId); @@ -16,16 +14,16 @@ function setInputValue(screen, inputElement, value) { fireEvent.change(inputElement, {target: {value}}); } -describe("CreateContent Component From Expert Management", () => { +describe("CreateContent Component From Expert Management (create)", () => { describe("Rendering", () => { - it("Password TextField Rendered", async () => { + it("close button Rendered", async () => { render(); await waitFor(() => { const cancelBtn = screen.queryByText('بستن'); expect(cancelBtn).toBeInTheDocument(); }); }); - it("Password TextField Rendered", async () => { + it("confirm button Rendered", async () => { render(); await waitFor(() => { const cancelBtn = screen.queryByText('ثبت'); @@ -33,8 +31,6 @@ describe("CreateContent Component From Expert Management", () => { }); }); }); - describe("Behavioral", () => { - }); describe("Form Submission", () => { it('Should enable the submit button when the inputs are valid', async () => { render(); diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/PersonalInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/PersonalInfo/__tests__/index.test.js new file mode 100644 index 0000000..b8692d5 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/PersonalInfo/__tests__/index.test.js @@ -0,0 +1,219 @@ +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider"; +import * as Yup from "yup"; +import {Formik} from "formik"; +import PersonalInfo from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/PersonalInfo"; +import {useTranslations} from "next-intl"; +import Province from "@/components/dashboard/expert-management/Form/CreateForm/CreateContent/RestInfo/Province"; + + +const CreateFormMock = ({Component}) => { + const t = useTranslations(); + const validationSchema = Yup.object().shape({ + full_name: Yup.string().required(t("ExpertMangement.error_message_full_name")), + email: Yup.string().required(t("ExpertMangement.error_message_email")), + phone_number: Yup.string().required(t("ExpertMangement.error_message_phone_number")), + telephone_id: Yup.string().required(t("ExpertMangement.error_message_telephone_id")), + national_id: Yup.string().required(t("ExpertMangement.error_message_national_id")), + gender: Yup.string().required(t("ExpertMangement.error_message_gender")) + }); + return ( + { + }} + > + {formikProps => ()} + + ); +}; + + +describe("PersonalInfo Component From Expert Management (update)", () => { + describe("Rendering", () => { + it("full_name TextField Rendered", async () => { + render(); + await waitFor(() => { + const fullNameTextField = screen.queryByLabelText('نام کامل'); + expect(fullNameTextField).toBeInTheDocument(); + }); + }); + it("Email TextField Rendered", async () => { + render(); + await waitFor(() => { + const emailTextField = screen.queryByLabelText('پست الکترونیک'); + expect(emailTextField).toBeInTheDocument(); + }); + }); + it("Phone Number TextField Rendered", async () => { + render(); + await waitFor(() => { + const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); + expect(phoneNumberTextField).toBeInTheDocument(); + }); + }); + it("telephone id TextField Rendered", async () => { + render(); + await waitFor(() => { + const telephoneIdTextField = screen.queryByLabelText('کد تلفن'); + expect(telephoneIdTextField).toBeInTheDocument(); + }); + }); + it("National Id TextField Rendered", async () => { + render(); + await waitFor(() => { + const nationalIdTextField = screen.queryByLabelText('کد ملی'); + expect(nationalIdTextField).toBeInTheDocument(); + }); + }); + it("Gender Select Box Rendered", async () => { + render(); + await waitFor(() => { + const genderSelectBox = screen.getByTestId('select-box'); + expect(genderSelectBox).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + it("Name TextField Work Correctly", async () => { + render(); + const nameTextField = screen.queryByLabelText('نام کامل'); + fireEvent.change(nameTextField, {target: {value: 'exampleName'}}); + await act(() => { + expect(nameTextField).toHaveValue('exampleName'); + }) + }); + it("Email TextField Work Correctly", async () => { + render(); + const emailTextField = screen.queryByLabelText('پست الکترونیک'); + fireEvent.change(emailTextField, {target: {value: 'exampleEmail'}}); + await act(() => { + expect(emailTextField).toHaveValue('exampleEmail'); + }) + }); + it("Phone Number TextField Work Correctly", async () => { + render(); + const phoneNumberTextField = screen.queryByLabelText('شماره همراه'); + fireEvent.change(phoneNumberTextField, {target: {value: 'examplePhoneNumber'}}); + await act(() => { + expect(phoneNumberTextField).toHaveValue('examplePhoneNumber'); + }) + }); + it("Telephone Id TextField Work Correctly", async () => { + render(); + const telephoneIdTextField = screen.queryByLabelText('کد تلفن'); + fireEvent.change(telephoneIdTextField, {target: {value: 'exampleTelephoneId'}}); + await act(() => { + expect(telephoneIdTextField).toHaveValue('exampleTelephoneId'); + }) + }); + it("National Id TextField Work Correctly", async () => { + render(); + const nationalIdTextField = screen.queryByLabelText('کد ملی'); + fireEvent.change(nationalIdTextField, {target: {value: 'exampleNationalId'}}); + await act(() => { + expect(nationalIdTextField).toHaveValue('exampleNationalId'); + }) + }); + it("Gender Select Box Work Correctly", async () => { + render(); + const genderSelectBox = screen.getByTestId('select-box'); + const genderSelectOpener = await waitFor(() => screen.getByTestId("option-opener-gender")); + + await waitFor(() => { + expect(genderSelectBox).toBeInTheDocument(); + }); + + fireEvent.mouseDown(genderSelectOpener); + await waitFor(() => { + const selectItem = screen.queryByText("مرد"); + expect(selectItem).toBeInTheDocument(); + }); + + }); + }); + describe("validation", () => { + it('Should See Error When Name Input Is Empty', async () => { + render(); + + const nameInput = screen.queryByLabelText('نام کامل'); + + fireEvent.change(nameInput, {target: {value: ''}}); + fireEvent.blur(nameInput); + + await waitFor(() => { + expect(screen.queryByText("نام کامل خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When Email Input Is Empty', async () => { + render(); + + const emailInput = screen.queryByLabelText('پست الکترونیک'); + + fireEvent.change(emailInput, {target: {value: ''}}); + fireEvent.blur(emailInput); + + await waitFor(() => { + expect(screen.queryByText("پست الکترونیک خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When Phone Number Input Is Empty', async () => { + render(); + + const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + + fireEvent.change(phoneNumberInput, {target: {value: ''}}); + fireEvent.blur(phoneNumberInput); + + await waitFor(() => { + expect(screen.queryByText("شماره همراه خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When telephone Id Input Is Empty', async () => { + render(); + + const telephoneIdTextField = screen.queryByLabelText('کد تلفن'); + + fireEvent.change(telephoneIdTextField, {target: {value: ''}}); + fireEvent.blur(telephoneIdTextField); + + await waitFor(() => { + expect(screen.queryByText("کد تلفن خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should See Error When National Id Input Is Empty', async () => { + render(); + + const nationalIdInput = screen.queryByLabelText('کد ملی'); + + fireEvent.change(nationalIdInput, {target: {value: ''}}); + fireEvent.blur(nationalIdInput); + + await waitFor(() => { + expect(screen.queryByText("کد ملی خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should Select An Item With Valid Value of gender', async () => { + render(); + const genderInput = screen.getByTestId("input-gender") + const genderSelectOpener = await waitFor(() => screen.getByTestId("option-opener-gender")); + + fireEvent.mouseDown(genderSelectOpener); + const selectItem = await waitFor(() => screen.queryByText("مرد")); + expect(selectItem).toBeInTheDocument(); + fireEvent.click(selectItem); + await waitFor(() => { + expect(genderInput.value).toBe('male') + }); + }); + }) +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/PersonalInfo/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/PersonalInfo/index.jsx new file mode 100644 index 0000000..f92bf38 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/PersonalInfo/index.jsx @@ -0,0 +1,128 @@ +import {FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, TextField} from "@mui/material"; +import {useTranslations} from "next-intl"; + +const PersonalInfo = ({formik}) => { + const t = useTranslations(); + + const genderList = [ + {id: 1, name_en: "male", name_fa: "مرد"}, + {id: 2, name_en: "female", name_fa: "زن"} + ] + + return ( + + + + + + + + + + + + + + + + + + + {t("ExpertMangement.text_field_gender")} + + + {formik.touched.gender && formik.errors.gender ? formik.errors.gender : ""} + + + + + ) +} +export default PersonalInfo \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/Index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/Index.jsx new file mode 100644 index 0000000..4fc402a --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/Index.jsx @@ -0,0 +1,75 @@ +import {FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select, TextField} from "@mui/material"; +import {useTranslations} from "next-intl"; +import useRequest from "@/lib/app/hooks/useRequest"; +import useRole from "@/lib/app/hooks/useRole"; +import {log} from "next/dist/server/typescript/utils"; + +const PositionAndRole = ({formik}) => { + const t = useTranslations(); + const requestServer = useRequest() + const {roleList, isLoadingRoleList, errorRoleList} = useRole(); + + return ( + + + + + + + {t("ExpertMangement.text_field_roles")} + + + {formik.touched.roles && formik.errors.roles ? formik.errors.roles : ""} + + + + + ) +} +export default PositionAndRole \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/__tests__/index.test.js new file mode 100644 index 0000000..d6062c5 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/__tests__/index.test.js @@ -0,0 +1,96 @@ +import {fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import {Formik} from "formik"; +import MockAppWithProviders from "../../../../../../../../../../mocks/AppWithProvider"; +import PositionAndRole from "../../PositionAndRole"; + +const CreateFormMock = ({Component}) => { + const t = useTranslations(); + const validationSchema = Yup.object().shape({ + position: Yup.string().required(t("ExpertMangement.error_message_position")), + roles: Yup.string().required(t("ExpertMangement.error_message_roles")) + }); + return ( + { + }} + > + {formikProps => ()} + + ); +}; + +describe("PositionAndRole Component From Expert Management (update)", () => { + describe("Rendering", () => { + it("Position TextField Rendered", async () => { + render(); + await waitFor(() => { + const positionTextField = screen.queryByLabelText('سمت'); + expect(positionTextField).toBeInTheDocument(); + }); + }); + it("Role Select Box Rendered", async () => { + render(); + const roleSelect = screen.getByTestId('select-box'); + await waitFor(() => { + expect(roleSelect).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + it("Position TextField Work Correctly", async () => { + render(); + const positionTextField = screen.queryByLabelText('سمت'); + fireEvent.change(positionTextField, {target: {value: 'examplePosition'}}); + await waitFor(() => { + expect(positionTextField).toHaveValue('examplePosition'); + }) + }); + it("Role Select Box Work Correctly", async () => { + render(); + const roleSelect = screen.getByTestId("option-opener-role"); + await waitFor(() => { + expect(roleSelect).toBeInTheDocument(); + }); + fireEvent.mouseDown(roleSelect); + await waitFor(() => { + const selectItem = screen.queryByText("ادمین"); + expect(selectItem).toBeInTheDocument(); + }); + }); + }); + describe("validation", () => { + it('Should See Error When Position Input Is Empty', async () => { + render(); + + const positionInput = screen.queryByLabelText('سمت'); + + fireEvent.change(positionInput, {target: {value: ''}}); + fireEvent.blur(positionInput); + + await waitFor(() => { + expect(screen.queryByText("سمت خود را وارد کنید")).toBeInTheDocument() + }); + }); + it('Should Select An Item With Valid Value of role', async () => { + render(); + const roleInput = await waitFor(() => screen.getByTestId("input-role-id")); + const roleSelectOpener = await waitFor(() => screen.getByTestId("option-opener-role")); + + fireEvent.mouseDown(roleSelectOpener); + const selectItem = await waitFor(() => screen.queryByText("ادمین")); + expect(selectItem).toBeInTheDocument(); + fireEvent.click(selectItem); + await waitFor(() => { + expect(roleInput.value).toBe('1') + }); + }); + }) +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province/__tests__/index.test.js new file mode 100644 index 0000000..d727188 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province/__tests__/index.test.js @@ -0,0 +1,71 @@ +import {fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import {Formik} from "formik"; +import Province from "../../Province"; +import MockAppWithProviders from "../../../../../../../../../../mocks/AppWithProvider"; + +const CreateFormMock = ({Component}) => { + const t = useTranslations(); + const validationSchema = Yup.object().shape({ + province_id: Yup.string().required(t("ExpertMangement.error_message_province_id")), + }); + return ( + { + }} + > + {formikProps => ()} + + ); +}; + +describe("Province Component From Expert Management (update)", () => { + describe("Rendering", () => { + it("Province Select Box Rendered", async () => { + render(); + await waitFor(() => { + const provinceSelectBox = screen.getByTestId('select-box'); + expect(provinceSelectBox).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + it("Province Select Box Work Correctly", async () => { + render(); + const provinceSelectBox = screen.getByTestId('select-box'); + const provinceSelectOpener = await waitFor(() => screen.getByTestId("option-opener-province")); + + await waitFor(() => { + expect(provinceSelectBox).toBeInTheDocument(); + }); + + fireEvent.mouseDown(provinceSelectOpener); + await waitFor(() => { + const selectItem = screen.queryByText("آذربایجان شرقی"); + expect(selectItem).toBeInTheDocument(); + }); + + }); + }); + describe("validation", () => { + it('Should Select An Item With Valid Value of province', async () => { + render(); + const provinceInput = screen.getByTestId("input-province-id") + const provinceSelectOpener = await waitFor(() => screen.getByTestId("option-opener-province")); + + fireEvent.mouseDown(provinceSelectOpener); + const selectItem = await waitFor(() => screen.queryByText("آذربایجان شرقی")); + expect(selectItem).toBeInTheDocument(); + fireEvent.click(selectItem); + await waitFor(() => { + expect(provinceInput.value).toBe('1') + }); + }); + }) +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province/index.jsx new file mode 100644 index 0000000..763465e --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province/index.jsx @@ -0,0 +1,61 @@ +import {FormControl, FormHelperText, Grid, InputLabel, MenuItem, Select} from "@mui/material"; +import {useTranslations} from "next-intl"; +import useProvince from "@/lib/app/hooks/useProvince"; +import useRequest from "@/lib/app/hooks/useRequest"; + +const Province = ({formik}) => { + const t = useTranslations(); + const requestServer = useRequest() + const {provinceList, isLoadingProvinceList, errorProvinceList} = useProvince(); + + return ( + + + + {t("ExpertMangement.text_field_province_id")} + + + {formik.touched.province_id && formik.errors.province_id ? formik.errors.province_id : ""} + + + + + ) +} +export default Province \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx new file mode 100644 index 0000000..072c096 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx @@ -0,0 +1,12 @@ +import Province from "./Province"; +import PositionAndRole from "./PositionAndRole"; + +const RestInfo = ({formik}) => { + return ( + <> + + + + ) +} +export default RestInfo \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/UserInfo/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/UserInfo/__tests__/index.test.js new file mode 100644 index 0000000..3fd341d --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/UserInfo/__tests__/index.test.js @@ -0,0 +1,62 @@ +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import MockAppWithProviders from "../../../../../../../../../mocks/AppWithProvider"; +import {useTranslations} from "next-intl"; +import * as Yup from "yup"; +import {Formik} from "formik"; +import UserInfo from "../../UserInfo"; + +const CreateFormMock = ({Component}) => { + const t = useTranslations(); + const validationSchema = Yup.object().shape({ + username: Yup.string().required(t("ExpertMangement.error_message_username")), + }); + return ( + { + }} + > + {formikProps => ()} + + ); +}; + +describe("UserInfo Component From Expert Management (update)", () => { + describe("Rendering", () => { + it("UserName TextField Rendered", async () => { + render(); + await waitFor(() => { + const usernameTextField = screen.queryByLabelText('نام کاربری'); + expect(usernameTextField).toBeInTheDocument(); + }); + }); + }); + describe("Behavioral", () => { + it("Username TextField Work Correctly", async () => { + render(); + const usernameTextField = screen.queryByLabelText('نام کاربری'); + fireEvent.change(usernameTextField, {target: {value: 'exampleUsername'}}); + await act(() => { + expect(usernameTextField).toHaveValue('exampleUsername'); + }) + }); + }); + describe("validation", () => { + it('Should See Error When Username Input Is Empty', async () => { + render(); + + const usernameInput = screen.queryByLabelText('نام کاربری'); + + fireEvent.change(usernameInput, {target: {value: ''}}); + fireEvent.blur(usernameInput); + + await waitFor(() => { + expect(screen.queryByText("نام کاربری خود را وارد کنید")).toBeInTheDocument() + }); + }); + }) +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/UserInfo/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/UserInfo/index.jsx new file mode 100644 index 0000000..d592ea5 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/UserInfo/index.jsx @@ -0,0 +1,29 @@ +import {Grid, TextField} from "@mui/material"; +import {useTranslations} from "next-intl"; + +const UserInfo = ({formik}) => { + const t = useTranslations(); + + return ( + <> + + + + + + + ) +} +export default UserInfo \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/__tests__/index.test.js new file mode 100644 index 0000000..765bc09 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/__tests__/index.test.js @@ -0,0 +1,87 @@ +import {fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import MockAppWithProviders from "../../../../../../../../mocks/AppWithProvider"; +import UpdateContent from "../../UpdateContent"; + +const row = { + original: { + avatar: null, + created_at: "2023-10-10T13:05:01.000000Z", + email: "fisher.sigrid@yahoo.com", + full_name: "Anibal Labadie", + gender: "female", + id: 85, + national_id: "5944646138", + phone_number: "09731311720", + position: "boss1", + province_fa: "اردبیل", + province_id: 3, + roles: [{ + created_at: "2023-10-10T13:03:18.000000Z", + guard_name: "api", + id: 2, + name: "manager", + name_fa: "مدیر" + }], + telephone_id: "tel-3110", + updated_at: "2023-10-17T10:57:12.000000Z", + username: "florence.kihn", + } +} + +function selectDropdownItem(screen, openerTestId, itemText) { + const opener = screen.getByTestId(openerTestId); + fireEvent.mouseDown(opener); + const selectItem = screen.queryByText(itemText); + fireEvent.click(selectItem); +} + +function setInputValue(screen, inputElement, value) { + fireEvent.change(inputElement, {target: {value}}); +} + +describe("UpdateContent Component From Expert Management (update)", () => { + describe("Rendering", () => { + it("close button Rendered", async () => { + render(); + await waitFor(() => { + const cancelBtn = screen.queryByText('بستن'); + expect(cancelBtn).toBeInTheDocument(); + }); + }); + it("confirm button Rendered", async () => { + render(); + await waitFor(() => { + const confirmBtn = screen.queryByText('ثبت'); + expect(confirmBtn).toBeInTheDocument(); + }); + }); + }); + describe("Form Submission", () => { + it('Should enable the submit button when the inputs are valid', async () => { + render(); + + const submitButton = screen.queryByText('ثبت'); + + const nameInput = screen.queryByLabelText('نام کامل'); + const usernameInput = screen.queryByLabelText('نام کاربری'); + const emailInput = screen.queryByLabelText('پست الکترونیک'); + const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + const telephoneIdInput = screen.queryByLabelText('کد تلفن'); + const nationalIdInput = screen.queryByLabelText('کد ملی'); + const positionInput = screen.queryByLabelText('سمت'); + + setInputValue(screen, nameInput, 'nameTest'); + setInputValue(screen, usernameInput, 'usernameTest'); + setInputValue(screen, emailInput, 'emailTest'); + setInputValue(screen, phoneNumberInput, 'phoneNumberTest'); + setInputValue(screen, telephoneIdInput, 'telephoneIdTest'); + setInputValue(screen, nationalIdInput, 'nationalIdTest'); + setInputValue(screen, positionInput, 'positionTest'); + + await waitFor(() => { + expect(submitButton).not.toBeDisabled(); + }); + }); + }) +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/index.jsx new file mode 100644 index 0000000..3b60506 --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/index.jsx @@ -0,0 +1,108 @@ +import {Box, Button, Chip, DialogActions, DialogContent, Divider,} from "@mui/material"; +import * as Yup from "yup"; +import {useTranslations} from "next-intl"; +import {useFormik} from "formik"; +import useRequest from "@/lib/app/hooks/useRequest"; +import {EXPERT_MANAGEMENT} from "@/core/data/apiRoutes"; +import PersonalInfo from "./PersonalInfo"; +import UserInfo from "./UserInfo"; +import RestInfo from "./RestInfo"; + +const UpdateContent = ({row, fetchUrl, mutate, setOpenUpdateDialog}) => { + const t = useTranslations(); + const requestServer = useRequest() + + const validationSchema = Yup.object().shape({ + full_name: Yup.string().required(t("ExpertMangement.error_message_full_name")), + username: Yup.string().required(t("ExpertMangement.error_message_username")), + email: Yup.string().required(t("ExpertMangement.error_message_email")), + phone_number: Yup.string().required(t("ExpertMangement.error_message_phone_number")), + telephone_id: Yup.string().required(t("ExpertMangement.error_message_telephone_id")), + gender: Yup.string().required(t("ExpertMangement.error_message_gender")), + national_id: Yup.string().required(t("ExpertMangement.error_message_national_id")), + position: Yup.string().required(t("ExpertMangement.error_message_position")), + province_id: Yup.string().required(t("ExpertMangement.error_message_province_id")), + roles: Yup.string().required(t("ExpertMangement.error_message_roles")) + }); + + const formik = useFormik({ + initialValues: { + full_name: row.original.full_name, + username: row.original.username, + email: row.original.email, + phone_number: row.original.phone_number, + telephone_id: row.original.telephone_id, + gender: row.original.gender, + national_id: row.original.national_id, + position: row.original.position, + province_id: row.original.province_id, + roles: row.original.roles[0].id + }, + validationSchema, + onSubmit: (values, {setSubmitting}) => { + const formData = new FormData(); + formData.append("full_name", values.full_name); + formData.append("national_id", values.national_id); + formData.append("phone_number", values.phone_number); + formData.append("telephone_id", values.telephone_id); + formData.append("gender", values.gender); + formData.append("email", values.email); + formData.append("username", values.username); + formData.append("province_id", values.province_id); + formData.append("position", values.position); + formData.append("roles", values.roles); + + requestServer(`${EXPERT_MANAGEMENT}/${row.original.id}`, 'post', {auth: true, data: formData}) + .then((response) => { + setOpenUpdateDialog(false) + mutate(fetchUrl) + }).catch(() => { + }).finally(() => { + setSubmitting(false); + }); + }, + }); + + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default UpdateContent \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/__tests__/index.test.js b/src/components/dashboard/expert-management/Form/UpdateForm/__tests__/index.test.js new file mode 100644 index 0000000..f824d6d --- /dev/null +++ b/src/components/dashboard/expert-management/Form/UpdateForm/__tests__/index.test.js @@ -0,0 +1,147 @@ +import {act, fireEvent, render, screen, waitFor} from "@testing-library/react"; +import React from 'react'; +import MockAppWithProviders from "../../../../../../../mocks/AppWithProvider"; +import UpdateForm from "../../UpdateForm"; + +const row = { + original: { + avatar: null, + created_at: "2023-10-10T13:05:01.000000Z", + email: "fisher.sigrid@yahoo.com", + full_name: "Anibal Labadie", + gender: "female", + id: 85, + national_id: "5944646138", + phone_number: "09731311720", + position: "boss1", + province_fa: "اردبیل", + province_id: 3, + roles: [{ + created_at: "2023-10-10T13:03:18.000000Z", + guard_name: "api", + id: 2, + name: "manager", + name_fa: "مدیر" + }], + telephone_id: "tel-3110", + updated_at: "2023-10-17T10:57:12.000000Z", + username: "florence.kihn", + } +} + +function selectDropdownItem(screen, openerTestId, itemText) { + const opener = screen.getByTestId(openerTestId); + fireEvent.mouseDown(opener); + const selectItem = screen.queryByText(itemText); + fireEvent.click(selectItem); +} + +function setInputValue(screen, inputElement, value) { + fireEvent.change(inputElement, {target: {value}}); +} + +describe("CreateForm Component From Expert Management", () => { + describe("Rendering", () => { + it("Update Expert Button Rendered", () => { + render(); + const UpdateButton = screen.getByTestId('update-button'); + expect(UpdateButton).toBeInTheDocument(); + }); + }); + describe("Behavioral", () => { + it("by Clicking Update Button Dialog Should Append To Document", async () => { + render(); + const UpdateButton = screen.getByTestId('update-button'); + fireEvent.click(UpdateButton); + await act(() => { + const UpdateDialog = screen.getByRole('dialog', {name: "ویرایش کارشناس"}) + expect(UpdateDialog).toBeInTheDocument(); + }); + }); + }); + describe("Form Submission", () => { + it('Should request to api and if get success close dialog', async () => { + render(); + + const UpdateButton = screen.getByTestId('update-button'); + fireEvent.click(UpdateButton); + + const submitButton = screen.queryByText('ثبت'); + + const nameInput = screen.queryByLabelText('نام کامل'); + const usernameInput = screen.queryByLabelText('نام کاربری'); + const emailInput = screen.queryByLabelText('پست الکترونیک'); + const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + const telephoneIdInput = screen.queryByLabelText('کد تلفن'); + const nationalIdInput = screen.queryByLabelText('کد ملی'); + const positionInput = screen.queryByLabelText('سمت'); + + selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); + selectDropdownItem(screen, "option-opener-role", "ادمین"); + selectDropdownItem(screen, "option-opener-gender", "مرد"); + + setInputValue(screen, nameInput, 'nameTest'); + setInputValue(screen, usernameInput, 'usernameTest'); + setInputValue(screen, emailInput, 'email@gmail.com'); + setInputValue(screen, phoneNumberInput, '0914577458'); + setInputValue(screen, telephoneIdInput, '091'); + setInputValue(screen, nationalIdInput, 'nationalIdTest'); + setInputValue(screen, positionInput, 'positionTest'); + + expect(submitButton).not.toBeDisabled(); + fireEvent.click(submitButton); + + await waitFor(() => { + const dialogContent = screen.queryByTestId('update-dialog-content'); + expect(dialogContent).not.toBeInTheDocument(); + }); + }); + it('Should request to api and if get error keep previous data', async () => { + render(); + + const UpdateButton = screen.getByTestId('update-button'); + fireEvent.click(UpdateButton); + + const submitButton = screen.queryByText('ثبت'); + + const nameInput = screen.queryByLabelText('نام کامل'); + const usernameInput = screen.queryByLabelText('نام کاربری'); + const emailInput = screen.queryByLabelText('پست الکترونیک'); + const phoneNumberInput = screen.queryByLabelText('شماره همراه'); + const telephoneIdInput = screen.queryByLabelText('کد تلفن'); + const nationalIdInput = screen.queryByLabelText('کد ملی'); + const positionInput = screen.queryByLabelText('سمت'); + const provinceInput = screen.getByTestId("input-province-id") + const roleInput = screen.getByTestId("input-role-id") + const genderInput = screen.getByTestId("input-gender") + + selectDropdownItem(screen, "option-opener-province", "آذربایجان شرقی"); + selectDropdownItem(screen, "option-opener-role", "ادمین"); + selectDropdownItem(screen, "option-opener-gender", "مرد"); + + setInputValue(screen, nameInput, 'nameTest'); + setInputValue(screen, usernameInput, 'usernameTest'); + setInputValue(screen, emailInput, 'emailTest@gmail.com'); + setInputValue(screen, phoneNumberInput, '0914577458'); + setInputValue(screen, telephoneIdInput, '091'); + setInputValue(screen, nationalIdInput, 'nationalIdTest'); + setInputValue(screen, positionInput, 'positionTest'); + + expect(submitButton).not.toBeDisabled(); + await fireEvent.click(submitButton); + + await waitFor(() => { + expect(nameInput).toHaveValue('nameTest'); + expect(usernameInput).toHaveValue('usernameTest'); + expect(emailInput).toHaveValue('emailTest@gmail.com'); + expect(phoneNumberInput).toHaveValue('0914577458'); + expect(telephoneIdInput).toHaveValue('091'); + expect(nationalIdInput).toHaveValue('nationalIdTest'); + expect(positionInput).toHaveValue('positionTest'); + expect(provinceInput).toHaveValue('1'); + expect(roleInput).toHaveValue('1'); + expect(genderInput).toHaveValue('male'); + }); + }); + }) +}); \ No newline at end of file diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/index.jsx index 59da7cd..55e7429 100644 --- a/src/components/dashboard/expert-management/Form/UpdateForm/index.jsx +++ b/src/components/dashboard/expert-management/Form/UpdateForm/index.jsx @@ -1,7 +1,33 @@ -const Update = () => { - return ( - <> - ) -} +import {useTranslations} from "next-intl"; +import {Dialog, DialogTitle, IconButton, Tooltip} from "@mui/material"; +import EditIcon from '@mui/icons-material/Edit'; +import {useState} from "react"; +import UpdateContent from "./UpdateContent"; -export default Update \ No newline at end of file + +const Update = ({row, fetchUrl, mutate}) => { + const t = useTranslations(); + const [openUpdateDialog, setOpenUpdateDialog] = useState(false); + + return ( + <> + + { + setOpenUpdateDialog(true) + }} + > + + + + + {t("ExpertMangement.update_expert")} + + + + ); +}; +export default Update; \ No newline at end of file diff --git a/src/lib/app/hooks/useProvince.jsx b/src/lib/app/hooks/useProvince.jsx index 359eff4..2bc8c6b 100644 --- a/src/lib/app/hooks/useProvince.jsx +++ b/src/lib/app/hooks/useProvince.jsx @@ -16,7 +16,8 @@ const useProvince = () => { const {data, isLoading} = useSWR(GET_PROVINCE_LIST, fetcher, { revalidateIfStale: false, revalidateOnFocus: false, - revalidateOnReconnect: false + revalidateOnReconnect: false, + keepPreviousData: true }); return { diff --git a/src/lib/app/hooks/useRole.jsx b/src/lib/app/hooks/useRole.jsx index fc3dd18..b4c231c 100644 --- a/src/lib/app/hooks/useRole.jsx +++ b/src/lib/app/hooks/useRole.jsx @@ -16,7 +16,8 @@ const useRole = () => { const {data, isLoading} = useSWR(GET_ROLE_LIST, fetcher, { revalidateIfStale: false, revalidateOnFocus: false, - revalidateOnReconnect: false + revalidateOnReconnect: false, + keepPreviousData: true }); return { From cba102102c3c633c35f21d23dbf20d511e40c32b Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Wed, 18 Oct 2023 11:49:04 +0330 Subject: [PATCH 17/20] CFE-3 Fixed test --- .../Form/UpdateForm/UpdateContent/RestInfo/index.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx index 072c096..824f1cb 100644 --- a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx @@ -1,5 +1,6 @@ -import Province from "./Province"; -import PositionAndRole from "./PositionAndRole"; +import PositionAndRole + from "@/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole"; +import Province from "@/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province"; const RestInfo = ({formik}) => { return ( From e0c6f4c0a1145e3a4076ef00b8b327b527a12dcb Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Wed, 18 Oct 2023 11:58:59 +0330 Subject: [PATCH 18/20] CFE-3 Fixed test --- .../RestInfo/PositionAndRole/{Index.jsx => index.jsx} | 0 .../Form/UpdateForm/UpdateContent/RestInfo/index.jsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/{Index.jsx => index.jsx} (100%) diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/Index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/index.jsx similarity index 100% rename from src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/Index.jsx rename to src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole/index.jsx diff --git a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx index 824f1cb..36c1877 100644 --- a/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx +++ b/src/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/index.jsx @@ -1,6 +1,6 @@ +import Province from "@/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province"; import PositionAndRole from "@/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/PositionAndRole"; -import Province from "@/components/dashboard/expert-management/Form/UpdateForm/UpdateContent/RestInfo/Province"; const RestInfo = ({formik}) => { return ( From 207c4d3fda6cfbc722827ac2db9eb5ffcb00797f Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Wed, 18 Oct 2023 12:07:35 +0330 Subject: [PATCH 19/20] CFE-3 Fixed test --- .../expert-management/DataTable/__tests__/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js b/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js index 3b7f516..eaad727 100644 --- a/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js @@ -7,7 +7,7 @@ describe("ExpertManagementDatatable Component From Expert Management", () => { it("Table Headers Rendered", () => { render(); const idHeader = screen.queryByText("کد یکتا"); - const nameHeader = screen.queryByText("نام"); + const nameHeader = screen.queryByText("نام کامل"); const usernameHeader = screen.queryByText("نام کاربری"); const emailHeader = screen.queryByText("پست الکترونیک"); const phone_numberHeader = screen.queryByText("شماره همراه"); From 606b9addc9fcb370c3154fcbaf309d12519091ce Mon Sep 17 00:00:00 2001 From: AmirHossein Mahmoodi Date: Wed, 18 Oct 2023 13:27:40 +0330 Subject: [PATCH 20/20] CFE-3 Fixed test --- public/locales/fa/app.json | 3 +++ .../DataTable/__tests__/index.test.js | 4 ++-- .../dashboard/expert-management/DataTable/index.jsx | 13 +++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/public/locales/fa/app.json b/public/locales/fa/app.json index 865f83d..c17c938 100644 --- a/public/locales/fa/app.json +++ b/public/locales/fa/app.json @@ -201,6 +201,9 @@ "position": "سمت", "province_fa": "استان", "role_name": "نقش", + "gender": "جنسیت", + "male": "مرد", + "female": "زن", "updated_at": "آخرین بروزرسانی", "create": "افزودن کارشناس", "personal_info": "مشخصات کارشناس", diff --git a/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js b/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js index eaad727..0ed26eb 100644 --- a/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js +++ b/src/components/dashboard/expert-management/DataTable/__tests__/index.test.js @@ -14,8 +14,8 @@ describe("ExpertManagementDatatable Component From Expert Management", () => { const national_idHeader = screen.queryByText("کد ملی"); const positionHeader = screen.queryByText("سمت"); const province_nameHeader = screen.queryByText("استان"); - const city_nameHeader = screen.queryByText("شهر"); const role_nameHeader = screen.queryByText("نقش"); + const genderHeader = screen.queryByText("جنسیت"); const updated_atHeader = screen.queryByText("آخرین بروزرسانی"); expect(idHeader).toBeInTheDocument(); expect(nameHeader).toBeInTheDocument(); @@ -25,8 +25,8 @@ describe("ExpertManagementDatatable Component From Expert Management", () => { expect(national_idHeader).toBeInTheDocument(); expect(positionHeader).toBeInTheDocument(); expect(province_nameHeader).toBeInTheDocument(); - expect(city_nameHeader).toBeInTheDocument(); expect(role_nameHeader).toBeInTheDocument(); + expect(genderHeader).toBeInTheDocument(); expect(updated_atHeader).toBeInTheDocument(); }); }); diff --git a/src/components/dashboard/expert-management/DataTable/index.jsx b/src/components/dashboard/expert-management/DataTable/index.jsx index 697fab1..9c4e763 100644 --- a/src/components/dashboard/expert-management/DataTable/index.jsx +++ b/src/components/dashboard/expert-management/DataTable/index.jsx @@ -127,6 +127,19 @@ function ExpertManagementDataTable() { {renderedCellValue} ), }, + { + accessorFn: (row) => row.gender, + id: "gender", + header: t("ExpertMangement.gender"), + enableColumnFilter: false, + datatype: "text", + filterFn: "contains", + columnFilterModeOptions: ["contains", "equals", "notEquals"], + Cell: ({renderedCellValue}) => ( + {renderedCellValue === "male" ? t("ExpertMangement.male") : t("ExpertMangement.female")} + ), + }, { accessorFn: (row) => moment(row.updated_at).locale("fa").format("HH:mm | yyyy/MM/DD"),