| @@ -166,6 +166,42 @@ describe("invite reducer tests default", () => { | |||
| expect(dispatchedActions).toContainEqual(inviteUserSuccess()); | |||
| }); | |||
| it("should run inviteUser saga function with actions and call response success", async () => { | |||
| const dispatchedActions = []; | |||
| // we don't want to perform an actual api call in our tests | |||
| // so we will mock the getAllUsers api with jest | |||
| // this will mutate the dependency which we may reset if other tests | |||
| // are dependent on it | |||
| const mockedCall = { data: { message: "Link has been sent!" } }; | |||
| api.inviteUserRequest = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| invite: { | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }, | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mock = jest.fn() | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, invite, { | |||
| payload: { | |||
| invite:{ | |||
| firstName: "st", | |||
| lastName: "Test", | |||
| email: "test@dilig.net",}, | |||
| handleApiResponseSuccess: mock | |||
| }, | |||
| }).done; | |||
| expect(mock).toHaveBeenCalled(); | |||
| }); | |||
| it("should run inviteUser saga function with error actions in case of api error", async () => { | |||
| const dispatchedActions = []; | |||
| @@ -16,6 +16,7 @@ import { | |||
| finishProcess, | |||
| changeStatus, | |||
| changeInterviewer, | |||
| getApplicantProcesses, | |||
| } from "../../store/saga/processSaga"; | |||
| import { | |||
| setProcesses, | |||
| @@ -30,6 +31,10 @@ import { | |||
| setUpdateStatusErr, | |||
| setUpdateStatusSucc, | |||
| } from "../../store/actions/processes/processAction"; | |||
| import { | |||
| setApplicant, | |||
| setApplicantError, | |||
| } from "../../store/actions/processes/applicantAction"; | |||
| describe("SelectionProcessPage render tests", () => { | |||
| const cont = ( | |||
| @@ -158,6 +163,34 @@ describe("SelectionProcessPage render tests", () => { | |||
| expect(dispatchedActions).toContainEqual(setProcesses(filteredData)); | |||
| }); | |||
| it("should handle error in case of exception", async () => { | |||
| const dispatchedActions = []; | |||
| const filter = { | |||
| statuses: ["Zakazan", "Odrađen"], | |||
| dateStart: new Date(2023, 0, 5), | |||
| dateEnd: new Date(2024, 1, 1), | |||
| }; | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getAllFilteredProcessesReq = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, getFilteredProcesses, filter).done; | |||
| expect(dispatchedActions).toContainEqual( | |||
| setProcessesError(error.response.data.message) | |||
| ); | |||
| }); | |||
| it("should handle process to set it done in case of success", async () => { | |||
| // we push all dispatched actions to make assertions easier | |||
| // and our tests less brittle | |||
| @@ -307,13 +340,13 @@ describe("SelectionProcessPage render tests", () => { | |||
| it("should handle process status update error if exception is thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.updateStatus = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| @@ -389,7 +422,7 @@ describe("SelectionProcessPage render tests", () => { | |||
| processId: 2, | |||
| }, | |||
| // responseHandler: apiSuccess, | |||
| } | |||
| }, | |||
| }).done; | |||
| expect(api.updateInterviewer.mock.calls.length).toBe(1); | |||
| @@ -406,7 +439,7 @@ describe("SelectionProcessPage render tests", () => { | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn() | |||
| const mockfn = jest.fn(); | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeInterviewer, { | |||
| @@ -416,7 +449,7 @@ describe("SelectionProcessPage render tests", () => { | |||
| processId: 2, | |||
| }, | |||
| responseHandler: mockfn, | |||
| } | |||
| }, | |||
| }).done; | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| @@ -444,7 +477,7 @@ describe("SelectionProcessPage render tests", () => { | |||
| processId: 2, | |||
| }, | |||
| // responseHandler: mockfn, | |||
| } | |||
| }, | |||
| }).done; | |||
| expect(api.updateInterviewer.mock.calls.length).toBe(1); | |||
| @@ -462,7 +495,7 @@ describe("SelectionProcessPage render tests", () => { | |||
| }; | |||
| api.updateInterviewer = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn() | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| @@ -477,10 +510,57 @@ describe("SelectionProcessPage render tests", () => { | |||
| processId: 2, | |||
| }, | |||
| responseHandler: mockfn, | |||
| } | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("should handle applicant processess if succeeded", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: {} }; | |||
| api.getProcessesOfApplicant = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, getApplicantProcesses, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(api.getProcessesOfApplicant.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setApplicant(mockedCall.data)); | |||
| }); | |||
| it("should handle applicant processess error if exception is thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getProcessesOfApplicant = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, getApplicantProcesses, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(api.getProcessesOfApplicant.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setApplicantError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -3,20 +3,22 @@ import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import * as api from '../../request/registerRequest' | |||
| import * as api from "../../request/registerRequest"; | |||
| import { render } from "@testing-library/react"; | |||
| import UserDetails from "../../pages/UsersPage/UserDetails"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import { USER_DETAILS_REQ } from "../../store/actions/users/usersActionConstants"; | |||
| import { | |||
| USER_DETAILS_REQ, | |||
| } from "../../store/actions/users/usersActionConstants"; | |||
| import { registerSuccess } from "../../store/actions/register/registerActions"; | |||
| registerError, | |||
| registerSuccess, | |||
| } from "../../store/actions/register/registerActions"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { userDetails } from "../../store/saga/usersSaga"; | |||
| import { registerUser } from "../../store/saga/registerSaga"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("UserDetails reducer tests", () => { | |||
| let spyOnUseSelector; | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| @@ -52,17 +54,83 @@ describe("UserDetails reducer tests", () => { | |||
| await runSaga(fakeStore, registerUser, { | |||
| payload: { | |||
| password:'', | |||
| email:'', | |||
| confirm:'', | |||
| position:'', | |||
| linkedIn:'', | |||
| phone:'', | |||
| token:'', | |||
| model: { | |||
| password: "", | |||
| email: "", | |||
| confirm: "", | |||
| position: "", | |||
| linkedIn: "", | |||
| phone: "", | |||
| token: "", | |||
| }, | |||
| }, | |||
| }).done; | |||
| expect(api.register.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(registerSuccess()); | |||
| }); | |||
| it("should call handleApiResponseSuccess", async () => { | |||
| const dispatchedActions = []; | |||
| api.register = jest.fn(() => Promise.resolve()); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockFn = jest.fn() | |||
| await runSaga(fakeStore, registerUser, { | |||
| payload: { | |||
| model: { | |||
| password: "", | |||
| email: "", | |||
| confirm: "", | |||
| position: "", | |||
| linkedIn: "", | |||
| phone: "", | |||
| token: "", | |||
| }, | |||
| handleApiResponseSuccess: mockFn | |||
| }, | |||
| }).done; | |||
| expect(mockFn).toHaveBeenCalled(); | |||
| }); | |||
| it("should handle register error", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { response: { data: { message: "Error" } } }; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error") | |||
| api.register = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, registerUser, { | |||
| payload: { | |||
| password: "", | |||
| email: "", | |||
| confirm: "", | |||
| position: "", | |||
| linkedIn: "", | |||
| phone: "", | |||
| token: "", | |||
| }, | |||
| }).done; | |||
| expect(api.register.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(registerError("Error")); | |||
| }); | |||
| }); | |||
| @@ -11,8 +11,9 @@ import { | |||
| USER_DETAILS_REQ, | |||
| } from "../../store/actions/users/usersActionConstants"; | |||
| import { userDetails } from "../../store/saga/usersSaga"; | |||
| import { stateUserDetailsSuccess } from "../../store/actions/users/usersActions"; | |||
| import { stateUserDetailsSuccess, userDetailsError } from "../../store/actions/users/usersActions"; | |||
| import { runSaga } from "redux-saga"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| jest.mock("react-router-dom", () => ({ | |||
| ...jest.requireActual("react-router-dom"), | |||
| @@ -71,13 +72,37 @@ describe("UserDetails reducer tests", () => { | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mock = jest.fn() | |||
| await runSaga(fakeStore, userDetails, { | |||
| payload: { | |||
| id: 1, | |||
| handleApiResponseSuccess: mock | |||
| }, | |||
| }).done; | |||
| expect(api.userDetailsRequest.mock.calls.length).toBe(1); | |||
| expect(mock).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(stateUserDetailsSuccess(mockState.user.user)); | |||
| }); | |||
| it("should handle error if exception occurs", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| api.userDetailsRequest = jest.fn(() => Promise.reject({ response: {data:{message:"Error"}} })); | |||
| const fakeStore = { | |||
| getState: () => mockState.user, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, userDetails, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(api.userDetailsRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(userDetailsError("Error")); | |||
| }); | |||
| }); | |||
| @@ -10,14 +10,15 @@ import { runSaga } from "redux-saga"; | |||
| import { FETCH_USERS_REQ } from "../../store/actions/users/usersActionConstants"; | |||
| import { | |||
| deleteStateUser, | |||
| deleteUserError, | |||
| setEnableUsers, | |||
| setEnableUsersError, | |||
| setUsers, | |||
| setUsersError, | |||
| toggleSingleUser, | |||
| } from "../../store/actions/users/usersActions"; | |||
| import { deleteUser, enableUser, getUsers } from "../../store/saga/usersSaga"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("User management reducer tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| @@ -105,17 +106,43 @@ describe("User management reducer tests", () => { | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mock = jest.fn(); | |||
| await runSaga(fakeStore, enableUser, { | |||
| payload: { | |||
| id: 1, | |||
| handleApiResponseSuccess: mock, | |||
| }, | |||
| }).done; | |||
| expect(api.enableUserRequest.mock.calls.length).toBe(1); | |||
| expect(mock).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(setEnableUsers()); | |||
| expect(dispatchedActions).toContainEqual(toggleSingleUser()); | |||
| }); | |||
| it("should handle enableUser saga errors", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Server error"); | |||
| api.enableUserRequest = jest.fn(() => | |||
| Promise.reject({ response: { data: { message: "Server error" } } }) | |||
| ); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, enableUser, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(dispatchedActions).toContainEqual(setEnableUsersError("Server error")); | |||
| }); | |||
| it("should run deleteUser saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| @@ -135,4 +162,50 @@ describe("User management reducer tests", () => { | |||
| expect(api.deleteUserRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(deleteStateUser(1)); | |||
| }); | |||
| it("should run deleteUser saga function with actions and call response success", async () => { | |||
| const dispatchedActions = []; | |||
| api.deleteUserRequest = jest.fn(() => Promise.resolve({ data: 1 })); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mock = jest.fn(); | |||
| await runSaga(fakeStore, deleteUser, { | |||
| payload: { | |||
| id: 1, | |||
| handleApiResponseSuccess: mock, | |||
| }, | |||
| }).done; | |||
| expect(api.deleteUserRequest.mock.calls.length).toBe(1); | |||
| expect(mock).toHaveBeenCalled(); | |||
| }); | |||
| it("should handle error when deleteUser runs", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Server error"); | |||
| api.deleteUserRequest = jest.fn(() => | |||
| Promise.reject({ response: { data: { message: "Server error" } } }) | |||
| ); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, deleteUser, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(dispatchedActions).toContainEqual(deleteUserError("Server error")); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,26 @@ | |||
| import { render, screen } from "@testing-library/react"; | |||
| import { Provider } from "react-redux"; | |||
| import { Router } from "react-router-dom"; | |||
| import AppRoutes from "../../AppRoutes"; | |||
| import MainContainer from "../../components/Section/MainContainer"; | |||
| import store from "../../store"; | |||
| import history from "../../store/utils/history"; | |||
| describe("main container tests", () => { | |||
| const cont = ( | |||
| <Provider store={store}> | |||
| <Router history={history}> | |||
| <MainContainer> | |||
| <AppRoutes /> | |||
| </MainContainer> | |||
| </Router> | |||
| </Provider> | |||
| ); | |||
| it("Should render", () => { | |||
| const {container} = render(cont); | |||
| expect(screen.queryByTestId('default-route-div')).toBeDefined() | |||
| expect(container.getElementsByClassName('h-withHeader')[0]).not.toBeDefined() | |||
| }); | |||
| }); | |||
| @@ -20,7 +20,7 @@ const MainContainer = ({ children }) => { | |||
| const { pathname } = useLocation(); | |||
| return urls.includes(pathname) ? ( | |||
| <div className="">{children}</div> | |||
| <div data-testid="default-route-div" className="">{children}</div> | |||
| ) : pathname === "/register" ? ( | |||
| <FormProvider> | |||
| <div className="">{children}</div> | |||
| @@ -35,7 +35,7 @@ const MainContainer = ({ children }) => { | |||
| ) : ( | |||
| <div className=""> | |||
| <Navbar /> | |||
| <div className={pathname === CREATE_AD_PAGE ? "" : 'h-withHeader'}> | |||
| <div className={pathname === CREATE_AD_PAGE ? "" : "h-withHeader"}> | |||
| {children} | |||
| </div> | |||
| </div> | |||
| @@ -8,10 +8,7 @@ export function* registerUser({payload}) { | |||
| try { | |||
| yield call(register, payload.model); | |||
| yield put(registerSuccess()); | |||
| // console.log('ovde 1') | |||
| if(payload.handleApiResponseSuccess){ | |||
| // console.log('ovde 2') | |||
| yield call(payload.handleApiResponseSuccess) | |||
| } | |||
| } catch (error) { | |||
| @@ -21,6 +18,7 @@ export function* registerUser({payload}) { | |||
| } | |||
| } | |||
| } | |||
| export default function* registerSaga() { | |||
| yield all([ | |||
| takeEvery(REGISTER_REQUEST, registerUser), | |||