| @@ -0,0 +1,4 @@ | |||
| node_modules | |||
| npm-debug.log | |||
| build | |||
| .dockerignore | |||
| @@ -0,0 +1,2 @@ | |||
| REACT_APP_BASE_API_URL=https://portalgatewayapi.bullioninternational.info/ | |||
| @@ -0,0 +1,28 @@ | |||
| { | |||
| "extends": [ | |||
| "react-app", | |||
| "airbnb", | |||
| "prettier" | |||
| ], | |||
| "plugins": [ | |||
| "react", | |||
| "react-hooks", | |||
| "security" | |||
| ], | |||
| "rules": { | |||
| "react/jsx-filename-extension": "off", | |||
| "react/jsx-props-no-spreading": "off", | |||
| "react/button-has-type": "off", | |||
| "react/require-default-props": "off", | |||
| "import/no-extraneous-dependencies": "off", | |||
| "import/prefer-default-export": "off", | |||
| "consistent-return": "off", | |||
| "no-shadow": "off", | |||
| "no-use-before-define": "off", | |||
| "no-template-curly-in-string": "off", | |||
| "react-hooks/exhaustive-deps": "warn", | |||
| "prettier/prettier": ["error", { | |||
| "endOfLine":"auto" | |||
| }] | |||
| } | |||
| } | |||
| @@ -0,0 +1,22 @@ | |||
| { | |||
| "env": { | |||
| "browser": true, | |||
| "es2021": true | |||
| }, | |||
| "extends": [ | |||
| "eslint:recommended", | |||
| "plugin:react/recommended" | |||
| ], | |||
| "parserOptions": { | |||
| "ecmaFeatures": { | |||
| "jsx": true | |||
| }, | |||
| "ecmaVersion": 12, | |||
| "sourceType": "module" | |||
| }, | |||
| "plugins": [ | |||
| "react" | |||
| ], | |||
| "rules": { | |||
| } | |||
| } | |||
| @@ -0,0 +1,23 @@ | |||
| # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | |||
| # dependencies | |||
| /node_modules | |||
| /.pnp | |||
| .pnp.js | |||
| # testing | |||
| /coverage | |||
| # production | |||
| /build | |||
| # misc | |||
| .DS_Store | |||
| .env.local | |||
| .env.development.local | |||
| .env.test.local | |||
| .env.production.local | |||
| npm-debug.log* | |||
| yarn-debug.log* | |||
| yarn-error.log* | |||
| @@ -0,0 +1,13 @@ | |||
| FROM node:16.19.0-alpine as build | |||
| WORKDIR /app | |||
| COPY package.json ./ | |||
| COPY yarn.lock ./ | |||
| RUN yarn | |||
| COPY . . | |||
| RUN yarn build | |||
| # production environment | |||
| FROM nginx:stable-alpine | |||
| COPY --from=build /app/build /usr/share/nginx/html | |||
| COPY --from=build /app/nginx.conf /etc/nginx/conf.d/default.conf | |||
| EXPOSE 80 | |||
| CMD ["nginx", "-g", "daemon off;"] | |||
| @@ -0,0 +1,15 @@ | |||
| const faker = require('faker'); | |||
| module.exports = () => { | |||
| const items = []; | |||
| for (let id = 1; id <= 500; id++) { | |||
| items.push({ | |||
| id: id, | |||
| name: `${faker.commerce.productAdjective()} ${faker.commerce.productMaterial()} ${faker.commerce.product()}`, | |||
| color: faker.commerce.color(), | |||
| price: `$${faker.commerce.price()}`, | |||
| company: faker.company.companyName(), | |||
| }); | |||
| } | |||
| return { items }; | |||
| }; | |||
| @@ -0,0 +1,8 @@ | |||
| server { | |||
| listen 80; | |||
| location / { | |||
| root /usr/share/nginx/html; | |||
| index index.html index.htm; | |||
| try_files $uri $uri/ /index.html =404; | |||
| } | |||
| } | |||
| @@ -0,0 +1,91 @@ | |||
| { | |||
| "name": "web", | |||
| "version": "0.1.0", | |||
| "private": true, | |||
| "dependencies": { | |||
| "@emotion/react": "^11.5.0", | |||
| "@emotion/styled": "^11.3.0", | |||
| "@mui/icons-material": "^5.0.5", | |||
| "@mui/material": "^5.0.6", | |||
| "@mui/x-data-grid": "^5.0.1", | |||
| "@mui/x-date-pickers": "^5.0.10", | |||
| "@reduxjs/toolkit": "^1.5.1", | |||
| "@testing-library/jest-dom": "^5.13.0", | |||
| "@testing-library/user-event": "^12.8.3", | |||
| "@tinymce/tinymce-react": "^4.2.0", | |||
| "axios": "^0.21.1", | |||
| "css-mediaquery": "^0.1.2", | |||
| "date-fns": "^2.29.3", | |||
| "eslint-plugin-prettier": "^3.4.0", | |||
| "eslint-plugin-security": "^1.4.0", | |||
| "faker": "^5.5.3", | |||
| "formik": "^2.2.9", | |||
| "html-react-parser": "^3.0.4", | |||
| "i18next": "^20.3.1", | |||
| "json-server": "^0.17.0", | |||
| "jsonwebtoken": "^8.5.1", | |||
| "jwt-decode": "^3.1.2", | |||
| "lodash": "^4.17.21", | |||
| "lodash.isempty": "^4.4.0", | |||
| "owasp-password-strength-test": "^1.3.0", | |||
| "postcss": "^8.4.20", | |||
| "react": "^17.0.2", | |||
| "react-dom": "^17.0.2", | |||
| "react-dropzone": "^14.2.3", | |||
| "react-helmet-async": "^1.0.9", | |||
| "react-i18next": "^11.10.0", | |||
| "react-mentions": "^4.4.7", | |||
| "react-redux": "^7.2.4", | |||
| "react-router-dom": "^5.2.0", | |||
| "react-scripts": "4.0.3", | |||
| "react-select": "^4.3.1", | |||
| "react-slick": "^0.29.0", | |||
| "redux": "^4.1.0", | |||
| "redux-saga": "^1.1.3", | |||
| "sass": "^1.34.1", | |||
| "slick-carousel": "^1.8.1", | |||
| "use-dynamic-refs": "^1.0.0", | |||
| "web-vitals": "^1.1.2", | |||
| "yup": "^0.32.9" | |||
| }, | |||
| "scripts": { | |||
| "start": "react-scripts start", | |||
| "build": "react-scripts build", | |||
| "test": "react-scripts test", | |||
| "eject": "react-scripts eject", | |||
| "json-serve": "json-server ./db/db.js --port=4000" | |||
| }, | |||
| "eslintConfig": { | |||
| "extends": [ | |||
| "react-app", | |||
| "react-app/jest" | |||
| ] | |||
| }, | |||
| "browserslist": { | |||
| "production": [ | |||
| ">0.2%", | |||
| "not dead", | |||
| "not op_mini all" | |||
| ], | |||
| "development": [ | |||
| "last 1 chrome version", | |||
| "last 1 firefox version", | |||
| "last 1 safari version" | |||
| ] | |||
| }, | |||
| "devDependencies": { | |||
| "@testing-library/react": "^12.1.2", | |||
| "eslint": "^7.28.0", | |||
| "eslint-config-airbnb": "^18.2.1", | |||
| "eslint-config-prettier": "^8.3.0", | |||
| "eslint-plugin-import": "^2.23.4", | |||
| "eslint-plugin-jsx-a11y": "^6.4.1", | |||
| "eslint-plugin-react": "^7.24.0", | |||
| "eslint-plugin-react-hooks": "^4.2.0", | |||
| "jest": "^26.6.0", | |||
| "jest-dom": "^4.0.0", | |||
| "jest-mock-axios": "^4.7.0-beta4", | |||
| "prettier": "2.3.1", | |||
| "react-test-renderer": "^18.2.0" | |||
| } | |||
| } | |||
| @@ -0,0 +1,50 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="utf-8" /> | |||
| <link rel="icon" href="hrcenter.png" /> | |||
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |||
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | |||
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |||
| <link | |||
| href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro&display=swap" | |||
| rel="stylesheet" | |||
| /> | |||
| <meta name="theme-color" content="#000000" /> | |||
| <meta | |||
| name="description" | |||
| content="Web site created using create-react-app" | |||
| /> | |||
| <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | |||
| <!-- | |||
| manifest.json provides metadata used when your web app is installed on a | |||
| user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ | |||
| --> | |||
| <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> | |||
| <!-- | |||
| Notice the use of %PUBLIC_URL% in the tags above. | |||
| It will be replaced with the URL of the `public` folder during the build. | |||
| Only files inside the `public` folder can be referenced from the HTML. | |||
| Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will | |||
| work correctly both with client-side routing and a non-root public URL. | |||
| Learn how to configure a non-root public URL by running `npm run build`. | |||
| --> | |||
| <title>React App</title> | |||
| <script src="https://accounts.google.com/gsi/client" async defer></script> | |||
| </head> | |||
| <body> | |||
| <noscript>You need to enable JavaScript to run this app.</noscript> | |||
| <div id="root"></div> | |||
| <!-- | |||
| This HTML file is a template. | |||
| If you open it directly in the browser, you will see an empty page. | |||
| You can add webfonts, meta tags, or analytics to this file. | |||
| The build step will place the bundled scripts into the <body> tag. | |||
| To begin the development, run `npm start` or `yarn start`. | |||
| To create a production bundle, use `npm run build` or `yarn build`. | |||
| --> | |||
| </body> | |||
| </html> | |||
| @@ -0,0 +1,25 @@ | |||
| { | |||
| "short_name": "React App", | |||
| "name": "Create React App Sample", | |||
| "icons": [ | |||
| { | |||
| "src": "favicon.ico", | |||
| "sizes": "64x64 32x32 24x24 16x16", | |||
| "type": "image/x-icon" | |||
| }, | |||
| { | |||
| "src": "logo192.png", | |||
| "type": "image/png", | |||
| "sizes": "192x192" | |||
| }, | |||
| { | |||
| "src": "logo512.png", | |||
| "type": "image/png", | |||
| "sizes": "512x512" | |||
| } | |||
| ], | |||
| "start_url": ".", | |||
| "display": "standalone", | |||
| "theme_color": "#000000", | |||
| "background_color": "#ffffff" | |||
| } | |||
| @@ -0,0 +1,3 @@ | |||
| # https://www.robotstxt.org/robotstxt.html | |||
| User-agent: * | |||
| Disallow: | |||
| @@ -0,0 +1,38 @@ | |||
| .App { | |||
| text-align: center; | |||
| } | |||
| .App-logo { | |||
| height: 40vmin; | |||
| pointer-events: none; | |||
| } | |||
| @media (prefers-reduced-motion: no-preference) { | |||
| .App-logo { | |||
| animation: App-logo-spin infinite 20s linear; | |||
| } | |||
| } | |||
| .App-header { | |||
| background-color: #282c34; | |||
| min-height: 100vh; | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| justify-content: center; | |||
| font-size: calc(10px + 2vmin); | |||
| color: white; | |||
| } | |||
| .App-link { | |||
| color: #61dafb; | |||
| } | |||
| @keyframes App-logo-spin { | |||
| from { | |||
| transform: rotate(0deg); | |||
| } | |||
| to { | |||
| transform: rotate(360deg); | |||
| } | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| import React from "react"; | |||
| import { Router } from "react-router-dom"; | |||
| import { Helmet } from "react-helmet-async"; | |||
| import i18next from "i18next"; | |||
| import history from "./store/utils/history"; | |||
| import MainContainer from "./components/Section/MainContainer"; | |||
| import AppRoutes from "./AppRoutes"; | |||
| /* istanbul ignore file */ | |||
| function App() { | |||
| return ( | |||
| <> | |||
| <Router history={history}> | |||
| <Helmet> | |||
| <title>{i18next.t("app.title")}</title> | |||
| </Helmet> | |||
| <MainContainer> | |||
| <AppRoutes /> | |||
| </MainContainer> | |||
| </Router> | |||
| </> | |||
| ); | |||
| } | |||
| export default App; | |||
| @@ -0,0 +1,109 @@ | |||
| import React, { useEffect } from "react"; | |||
| import { Redirect, Route, Switch } from "react-router-dom"; | |||
| import { useDispatch } from "react-redux"; | |||
| import { refreshUserToken } from "./store/actions/login/loginActions"; | |||
| import { useLocation } from "react-router-dom"; | |||
| import { | |||
| ADS_PAGE, | |||
| AD_DETAILS_PAGE, | |||
| FORGOT_PASSWORD_PAGE, | |||
| FORGOT_PASSWORD_CONFIRMATION_PAGE, | |||
| NOT_FOUND_PAGE, | |||
| ERROR_PAGE, | |||
| BASE_PAGE, | |||
| RESET_PASSWORD_PAGE, | |||
| USERS_PAGE, | |||
| CANDIDATES_PAGE, | |||
| USER_DETAILS_PAGE, | |||
| CANDIDATES_DETAILS_PAGE, | |||
| SELECTION_PROCESS_PAGE, | |||
| SELECTION_PROCESS_OF_APPLICANT_PAGE, | |||
| PATTERNS_PAGE, | |||
| PATTERN_DETAILS_PAGE, | |||
| SCHEDULE_PAGE, | |||
| STATS_PAGE, | |||
| REGISTER_PAGE, | |||
| CREATE_AD_PAGE, | |||
| } from "./constants/pages"; | |||
| import LoginPage from "./pages/LoginPage/LoginPageMUI"; | |||
| import AdsPage from "./pages/AdsPage/AdsPage"; | |||
| import NotFoundPage from "./pages/ErrorPages/NotFoundPage"; | |||
| import ErrorPage from "./pages/ErrorPages/ErrorPage"; | |||
| import ForgotPasswordPage from "./pages/ForgotPasswordPage/ForgotPasswordPageMUI"; | |||
| import PrivateRoute from "./components/Router/PrivateRoute"; | |||
| import ForgotPasswordConfirmationPage from "./pages/ForgotPasswordPage/ForgotPasswordConfirmationPageMUI"; | |||
| import ResetPasswordPage from "./pages/ForgotPasswordPage/ResetPasswordPageMUI"; | |||
| import UsersPage from "./pages/UsersPage/UsersPage"; | |||
| import CandidatesPage from "./pages/CandidatesPage/CandidatesPage"; | |||
| import AdDetailsPage from "./pages/AdsPage/AdDetailsPage"; | |||
| import UserDetails from "./pages/UsersPage/UserDetails"; | |||
| import CandidateDetailsPage from "./pages/CandidatesPage/CandidateDetailsPage"; | |||
| import SelectionProcessPage from "./pages/SelectionProcessPage/SelectionProcessPage"; | |||
| import SelectionProcessOfApplicantPage from "./pages/SelectionProcessPage/SelectionProcessOfApplicantPage"; | |||
| import PatternsPage from "./pages/PatternsPage/PatternsPage"; | |||
| import PatternDetailsPage from "./pages/PatternsPage/PatternDetailsPage"; | |||
| import SchedulePage from "./pages/SchedulePage/SchedulePage"; | |||
| import StatsPage from "./pages/StatsPage/StatsPage"; | |||
| import RegisterPage from "./pages/RegisterPage/RegisterPage"; | |||
| import CreateAdPage from "./pages/AdsPage/CreateAdPage"; | |||
| const AppRoutes = () => { | |||
| const dispatch = useDispatch(); | |||
| const location = useLocation(); | |||
| useEffect(() => { | |||
| if (location.pathname === BASE_PAGE) { | |||
| return; | |||
| } | |||
| dispatch(refreshUserToken()); | |||
| }, [location]); | |||
| return ( | |||
| <Switch> | |||
| <Route exact path={BASE_PAGE} component={LoginPage} /> | |||
| <Route path={NOT_FOUND_PAGE} component={NotFoundPage} /> | |||
| {/* <Route path={USERS_PAGE} component={UsersPage} /> */} | |||
| <Route path={ERROR_PAGE} component={ErrorPage} /> | |||
| <Route path={FORGOT_PASSWORD_PAGE} component={ForgotPasswordPage} /> | |||
| <Route | |||
| path={FORGOT_PASSWORD_CONFIRMATION_PAGE} | |||
| component={ForgotPasswordConfirmationPage} | |||
| /> | |||
| <Route exact path={REGISTER_PAGE} component={RegisterPage} /> | |||
| <Route path={RESET_PASSWORD_PAGE} component={ResetPasswordPage} /> | |||
| <PrivateRoute exact path={ADS_PAGE} component={AdsPage} /> | |||
| <PrivateRoute exact path={AD_DETAILS_PAGE} component={AdDetailsPage} /> | |||
| <PrivateRoute exact path={USER_DETAILS_PAGE} component={UserDetails} /> | |||
| <PrivateRoute exact path={USERS_PAGE} component={UsersPage} /> | |||
| <PrivateRoute exact path={CANDIDATES_PAGE} component={CandidatesPage} /> | |||
| <PrivateRoute exact path={CREATE_AD_PAGE} component={CreateAdPage} /> | |||
| <PrivateRoute | |||
| exact | |||
| path={CANDIDATES_DETAILS_PAGE} | |||
| component={CandidateDetailsPage} | |||
| /> | |||
| <PrivateRoute | |||
| exact | |||
| path={SELECTION_PROCESS_PAGE} | |||
| component={SelectionProcessPage} | |||
| /> | |||
| <PrivateRoute | |||
| exact | |||
| path={SELECTION_PROCESS_OF_APPLICANT_PAGE} | |||
| component={SelectionProcessOfApplicantPage} | |||
| /> | |||
| <PrivateRoute | |||
| exact | |||
| path={PATTERN_DETAILS_PAGE} | |||
| component={PatternDetailsPage} | |||
| /> | |||
| <PrivateRoute exact path={PATTERNS_PAGE} component={PatternsPage} /> | |||
| <PrivateRoute exact path={SCHEDULE_PAGE} component={SchedulePage} /> | |||
| <PrivateRoute exact path={STATS_PAGE} component={StatsPage} /> | |||
| <Redirect from="*" to={NOT_FOUND_PAGE} /> | |||
| </Switch> | |||
| ); | |||
| }; | |||
| export default AppRoutes; | |||
| @@ -0,0 +1,27 @@ | |||
| import reducer from "../../../../store/reducers/ad/adReducer"; | |||
| import expect from "expect"; | |||
| import { setAd, setAdError } from "../../../../store/actions/ad/adActions"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("ad reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| ad: null, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setAdError("Error"))).toEqual({ | |||
| ad: null, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect(reducer(undefined, setAd(mockState.ads.ads[0]))).toEqual({ | |||
| ad: mockState.ads.ads[0], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,46 @@ | |||
| import reducer from "../../../../store/reducers/ad/adsReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setAds, | |||
| setAdsError, | |||
| setFilteredAds, | |||
| setFilteredAdsError, | |||
| } from "../../../../store/actions/ads/adsAction"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("ads reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| ads: [], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error when setAdsError is called", () => { | |||
| expect(reducer(undefined, setAdsError("Error"))).toEqual({ | |||
| ads: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set ads when setAds is called", () => { | |||
| expect(reducer(undefined, setAds(mockState.ads.ads[0]))).toEqual({ | |||
| ads: mockState.ads.ads[0], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error when setFilteredAdsError is called", () => { | |||
| expect(reducer(undefined, setFilteredAdsError("Error"))).toEqual({ | |||
| ads: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set ads when setFilteredAds is called", () => { | |||
| expect(reducer(undefined, setFilteredAds(mockState.ads.ads[0]))).toEqual({ | |||
| ads: mockState.ads.ads[0], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,26 @@ | |||
| import reducer from "../../../../store/reducers/ad/archiveActiveAdReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| archiveActiveAd, | |||
| archiveActiveAdError, | |||
| } from "../../../../store/actions/archiveActiveAd/archiveActiveAdActions"; | |||
| describe("archiveActiveAd reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, archiveActiveAdError("Error"))).toEqual({ | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect(reducer(undefined, archiveActiveAd())).toEqual({ | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,30 @@ | |||
| import reducer from "../../../../store/reducers/ad/archiveAdsReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setArchiveAds, | |||
| setArchiveAdsError, | |||
| } from "../../../../store/actions/archiveAds/archiveAdsActions"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("archiveAdsReducer reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| archiveAds: [], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setArchiveAdsError("Error"))).toEqual({ | |||
| archiveAds: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect(reducer(undefined, setArchiveAds(mockState.ads.ads))).toEqual({ | |||
| archiveAds: mockState.ads.ads, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,30 @@ | |||
| import reducer from "../../../../store/reducers/ad/createAdReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setCreateAd, | |||
| setCreateAdError, | |||
| } from "../../../../store/actions/createAd/createAdActions"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("createAd reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| ad: null, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setCreateAdError("Error"))).toEqual({ | |||
| ad: null, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect(reducer(undefined, setCreateAd(mockState.ads.ads[0]))).toEqual({ | |||
| ad: mockState.ads.ads[0], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,68 @@ | |||
| import reducer from "../../../store/reducers/technology/addAddTechnologiesReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| changeIsCheckedAddAdValue, | |||
| resetIsCheckedAddAdValue, | |||
| setTechnologiesAddAd, | |||
| setTechnologiesAddAdError, | |||
| } from "../../../store/actions/addAdTechnologies/addAdTechnologiesActions"; | |||
| describe("ad technologies reducer", () => { | |||
| it("should set techologies", () => { | |||
| expect( | |||
| reducer(undefined, setTechnologiesAddAd(["tech1", "tech2"])) | |||
| ).toEqual({ | |||
| technologies: ["tech1", "tech2"], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set error", () => { | |||
| expect(reducer(undefined, setTechnologiesAddAdError("Error"))).toEqual({ | |||
| technologies: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should check tech", () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| technologies: [ | |||
| { technologyId: 1, name: "T1", isChecked: false }, | |||
| { technologyId: 2, name: "T2", isChecked: false }, | |||
| ], | |||
| errorMessage: "", | |||
| }, | |||
| changeIsCheckedAddAdValue(1) | |||
| ) | |||
| ).toEqual({ | |||
| technologies: [ | |||
| { technologyId: 1, name: "T1", isChecked: true }, | |||
| { technologyId: 2, name: "T2", isChecked: false }, | |||
| ], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should reset checked tech", () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| technologies: [ | |||
| { technologyId: 1, name: "T1", isChecked: true }, | |||
| { technologyId: 2, name: "T2", isChecked: true }, | |||
| ], | |||
| errorMessage: "", | |||
| }, | |||
| resetIsCheckedAddAdValue() | |||
| ) | |||
| ).toEqual({ | |||
| technologies: [ | |||
| { technologyId: 1, name: "T1", isChecked: false }, | |||
| { technologyId: 2, name: "T2", isChecked: false }, | |||
| ], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,26 @@ | |||
| import reducer from "../../../store/reducers/applicants/applyForAdReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| applyForAd, | |||
| applyForAdError, | |||
| } from "../../../store/actions/applyForAd/applyForAdActions"; | |||
| describe("applyForAd reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, applyForAdError("Error"))).toEqual({ | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect(reducer(undefined, applyForAd())).toEqual({ | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,35 @@ | |||
| import reducer from "../../../store/reducers/candidates/candidateOptionsReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| fetchCandidateOptionsSuccess, | |||
| fetchCandidateOptionsError, | |||
| } from "../../../store/actions/candidates/candidatesActions"; | |||
| import { mockState } from "../../../mockState"; | |||
| describe("candidatesOptions reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| options: [], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, fetchCandidateOptionsError("Error"))).toEqual({ | |||
| options: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set options", () => { | |||
| expect( | |||
| reducer( | |||
| undefined, | |||
| fetchCandidateOptionsSuccess(mockState.options.options) | |||
| ) | |||
| ).toEqual({ | |||
| options: mockState.options.options, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,75 @@ | |||
| import reducer from "../../../store/reducers/candidate/candidateReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| fetchCandidateSuccess, | |||
| fetchCandidateError, | |||
| createCandidateCommentSuccess, | |||
| createCandidateCommentError, | |||
| deleteCandidateError, | |||
| deleteCandidateSuccess, | |||
| } from "../../../store/actions/candidate/candidateActions"; | |||
| import { mockState } from "../../../mockState"; | |||
| describe("candidate reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| candidate: {}, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error when fetchCandidateError is called", () => { | |||
| expect(reducer(undefined, fetchCandidateError("Error"))).toEqual({ | |||
| candidate: {}, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set candidate when fetchCandidateSuccess is called", () => { | |||
| expect( | |||
| reducer(undefined, fetchCandidateSuccess(mockState.candidate.candidate)) | |||
| ).toEqual({ | |||
| candidate: mockState.candidate.candidate, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error when createCandidateCommentError is called", () => { | |||
| expect(reducer(undefined, createCandidateCommentError("Error"))).toEqual({ | |||
| candidate: {}, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| // problem with comparing dateOfSending property of two states | |||
| // it("should add new comment for canidate", () => { | |||
| // const obj = { | |||
| // myObj: { content: "sfsdfsd" }, | |||
| // user: mockState.user.user, | |||
| // }; | |||
| // expect( | |||
| // reducer( | |||
| // { candidate: mockState.candidate.candidate, errorMessage: "" }, | |||
| // createCandidateCommentSuccess(obj) | |||
| // ) | |||
| // ).toEqual({ | |||
| // candidate: { ...mockState.candidate.candidate, obj }, | |||
| // errorMessage: "", | |||
| // }); | |||
| // }); | |||
| it("should set the state error when deleteCandidateError is called", () => { | |||
| expect(reducer(undefined, deleteCandidateError("Error"))).toEqual({ | |||
| candidate: {}, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set candidate when deleteCandidateSuccess is called", () => { | |||
| fetchCandidateSuccess(mockState.candidate.candidate); | |||
| expect(reducer(undefined, deleteCandidateSuccess())).toEqual({ | |||
| candidate: {}, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,66 @@ | |||
| import reducer from "../../../store/reducers/candidates/candidatesReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| filterCandidatesError, | |||
| filterCandidatesSuccess, | |||
| fetchAdsCandidatesSuccess, | |||
| fetchAdsCandidatesError, | |||
| } from "../../../store/actions/candidates/candidatesActions"; | |||
| import { mockState } from "../../../mockState"; | |||
| describe("candidates reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| candidates: [], | |||
| adsCandidates: [], | |||
| errorMessage: "", | |||
| pagination: 0, | |||
| }); | |||
| }); | |||
| it("should set the state error when filterCandidates is called", () => { | |||
| expect(reducer(undefined, filterCandidatesError("Error"))).toEqual({ | |||
| candidates: [], | |||
| adsCandidates: [], | |||
| errorMessage: "Error", | |||
| pagination: 0, | |||
| }); | |||
| }); | |||
| it("should set candidates and pagination", () => { | |||
| expect( | |||
| reducer( | |||
| undefined, | |||
| filterCandidatesSuccess({ items: [mockState.candidates[0]], total: 1 }) | |||
| ) | |||
| ).toEqual({ | |||
| candidates: [mockState.candidates[0]], | |||
| adsCandidates: [], | |||
| errorMessage: "", | |||
| pagination: 1, | |||
| }); | |||
| }); | |||
| it("should set the state error when fetchAdsCandidates is called ", () => { | |||
| expect(reducer(undefined, fetchAdsCandidatesError("Error"))).toEqual({ | |||
| candidates: [], | |||
| adsCandidates: [], | |||
| errorMessage: "Error", | |||
| pagination: 0, | |||
| }); | |||
| }); | |||
| it("should set adsCandidates", () => { | |||
| expect( | |||
| reducer( | |||
| undefined, | |||
| fetchAdsCandidatesSuccess(mockState.candidates.adsCandidates) | |||
| ) | |||
| ).toEqual({ | |||
| candidates: [], | |||
| adsCandidates: mockState.candidates.adsCandidates, | |||
| errorMessage: "", | |||
| pagination: 0, | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,29 @@ | |||
| import reducer from "../../../store/reducers/candidates/initProcessReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| fetchInitProcessSuccess, | |||
| fetchInitProcessError, | |||
| } from "../../../store/actions/candidates/candidatesActions"; | |||
| describe("initProcces reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, fetchInitProcessError("Error"))).toEqual({ | |||
| isSuccess: false, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect(reducer(undefined, fetchInitProcessSuccess())).toEqual({ | |||
| isSuccess: true, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,26 @@ | |||
| import reducer from "../../../store/reducers/user/inviteUserReducer"; | |||
| import expect from "expect"; | |||
| import { inviteUserError, inviteUserSuccess } from "../../../store/actions/users/usersActions"; | |||
| describe("invite user reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, inviteUserError("Error"))).toEqual({ | |||
| isSuccess: false, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect(reducer(undefined, inviteUserSuccess())).toEqual({ | |||
| isSuccess: true, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,25 @@ | |||
| import reducer from "../../../store/reducers/loading/loadingReducer"; | |||
| import expect from "expect"; | |||
| import { setAppReady } from "../../../store/actions/app/appActions"; | |||
| import { APP_LOADING } from "../../../store/actions/app/appActionConstants"; | |||
| import { resetLoginState } from "../../../store/actions/login/loginActions"; | |||
| describe("loading reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| [APP_LOADING]: true, | |||
| }); | |||
| }); | |||
| it("should set loader to true", () => { | |||
| expect(reducer(false, resetLoginState())).toEqual({ | |||
| [APP_LOADING]: true, | |||
| }); | |||
| }); | |||
| it("should set loader to false", () => { | |||
| expect(reducer(true, setAppReady())).toEqual({ | |||
| [APP_LOADING]: false, | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,55 @@ | |||
| import reducer from "../../../store/reducers/login/loginReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| fetchUserError, | |||
| resetLoginState, | |||
| clearLoginErrors, | |||
| generateTokenSuccess, | |||
| generateTokenError, | |||
| } from "../../../store/actions/login/loginActions"; | |||
| describe("login reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, fetchUserError("Error"))).toEqual({ | |||
| email: "", | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("reset login state", () => { | |||
| expect(reducer(undefined, resetLoginState())).toEqual({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("clear login errors", () => { | |||
| fetchUserError("Error"); | |||
| expect(reducer(undefined, clearLoginErrors())).toEqual({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("generate token", () => { | |||
| expect(reducer(undefined, generateTokenSuccess("some token"))).toEqual({ | |||
| email: "", | |||
| errorMessage: "", | |||
| token: "some token", | |||
| }); | |||
| }); | |||
| it("generate token error", () => { | |||
| expect(reducer(undefined, generateTokenError("some token error"))).toEqual({ | |||
| email: "", | |||
| errorMessage: "some token error", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,32 @@ | |||
| import reducer from "../../../../store/reducers/pattern/createPatternReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| createPattern, | |||
| createPatternError, | |||
| } from "../../../../store/actions/createPattern/createPatternActions"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("createPattern reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| pattern: null, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, createPatternError("Error"))).toEqual({ | |||
| pattern: null, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect( | |||
| reducer(undefined, createPattern(mockState.patterns.patterns)) | |||
| ).toEqual({ | |||
| pattern: mockState.patterns.patterns, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,32 @@ | |||
| import reducer from "../../../../store/reducers/pattern/patternApplicantsReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setPatternApplicants, | |||
| setPatternApplicantsError, | |||
| } from "../../../../store/actions/patternApplicants/patternApplicantsActions"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("patternApplicants reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| patternApplicants: [], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setPatternApplicantsError("Error"))).toEqual({ | |||
| patternApplicants: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect( | |||
| reducer(undefined, setPatternApplicants(mockState.patterns.patterns)) | |||
| ).toEqual({ | |||
| patternApplicants: mockState.patterns.patterns, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,32 @@ | |||
| import reducer from "../../../../store/reducers/pattern/patternReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setPattern, | |||
| setPatternError, | |||
| } from "../../../../store/actions/pattern/patternActions"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("pattern reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| pattern: null, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setPatternError("Error"))).toEqual({ | |||
| pattern: null, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect( | |||
| reducer(undefined, setPattern(mockState.patterns.patterns[0])) | |||
| ).toEqual({ | |||
| pattern: mockState.patterns.patterns[0], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,50 @@ | |||
| import reducer from "../../../../store/reducers/pattern/patternsReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setPatterns, | |||
| setPatternsError, | |||
| setFilteredPatterns, | |||
| setFilteredPatternsError, | |||
| } from "../../../../store/actions/patterns/patternsActions"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("patterns reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| patterns: [], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error when setPatternsError is called", () => { | |||
| expect(reducer(undefined, setPatternsError("Error"))).toEqual({ | |||
| patterns: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success when setPatterns is called", () => { | |||
| expect( | |||
| reducer(undefined, setPatterns(mockState.patterns.patterns)) | |||
| ).toEqual({ | |||
| patterns: mockState.patterns.patterns, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error when setFilteredPatternsError is called", () => { | |||
| expect(reducer(undefined, setFilteredPatternsError("Error"))).toEqual({ | |||
| patterns: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success when setFilteredPatterns is called", () => { | |||
| expect( | |||
| reducer(undefined, setFilteredPatterns(mockState.patterns.patterns)) | |||
| ).toEqual({ | |||
| patterns: mockState.patterns.patterns, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,51 @@ | |||
| import reducer from "../../../../store/reducers/pattern/scheduleAppointmentReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| scheduleAppointment, | |||
| scheduleAppointmentError, | |||
| clearNotSentEmailsArray, | |||
| } from "../../../../store/actions/scheduleAppointment/scheduleAppointmentActions"; | |||
| describe("patterns reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| notSentEmails: null, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error when setScheduleAppointmentErrorMessage is called", () => { | |||
| expect(reducer(undefined, scheduleAppointmentError("Error"))).toEqual({ | |||
| notSentEmails: null, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success when scheduleAppointment with an empty array as argument is called", () => { | |||
| expect( | |||
| reducer(undefined, scheduleAppointment({ notSentEmails: [] })) | |||
| ).toEqual({ | |||
| notSentEmails: [], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state success when scheduleAppointment with an null as argument is called", () => { | |||
| expect(reducer(undefined, scheduleAppointment(null))).toEqual({ | |||
| notSentEmails: null, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state success when clearNotSentEmailsArray is called", () => { | |||
| expect( | |||
| reducer( | |||
| { notSentEmails: [], errorMessage: "" }, | |||
| clearNotSentEmailsArray() | |||
| ) | |||
| ).toEqual({ | |||
| notSentEmails: null, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,32 @@ | |||
| import reducer from "../../../../store/reducers/pattern/updatePatternReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| updatePattern, | |||
| updatePatternError, | |||
| } from "../../../../store/actions/updatePattern/updatePatternActions"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("updatePattern reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| pattern: null, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, updatePatternError("Error"))).toEqual({ | |||
| pattern: null, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect( | |||
| reducer(undefined, updatePattern(mockState.patterns.patterns[0])) | |||
| ).toEqual({ | |||
| pattern: mockState.patterns.patterns[0], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,32 @@ | |||
| import reducer from "../../../../store/reducers/processes/applicantWithProcessesReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setApplicant, | |||
| setApplicantError | |||
| } from "../../../../store/actions/processes/applicantAction"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("createPattern reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| applicant: {}, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setApplicantError("Error"))).toEqual({ | |||
| applicant: {}, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect( | |||
| reducer(undefined, setApplicant(mockState.candidate.candidate)) | |||
| ).toEqual({ | |||
| applicant: mockState.candidate.candidate, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,37 @@ | |||
| import reducer from "../../../../store/reducers/processes/interviewerUpdateReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setUpdateInterviewerSucc, | |||
| setUpdateInterviewerReq, | |||
| setUpdateInterviewerErr | |||
| } from "../../../../store/actions/processes/processAction"; | |||
| describe("interviewerUpdateReducer reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| updateSuccess: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setUpdateInterviewerErr("Error"))).toEqual({ | |||
| updateSuccess: false, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the updateSuccess to true", () => { | |||
| expect(reducer(undefined, setUpdateInterviewerSucc())).toEqual({ | |||
| updateSuccess: true, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the updateSuccess to false", () => { | |||
| expect(reducer(undefined, setUpdateInterviewerReq())).toEqual({ | |||
| updateSuccess: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,36 @@ | |||
| import reducer from "../../../../store/reducers/processes/processReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setDoneProcess, | |||
| setDoneProcessError, | |||
| } from "../../../../store/actions/processes/processAction"; | |||
| describe("process reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| doneProcess: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setDoneProcessError("Error"))).toEqual({ | |||
| doneProcess: false, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the doneProcess to true", () => { | |||
| expect(reducer(undefined, setDoneProcess(true))).toEqual({ | |||
| doneProcess: true, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the doneProcess to false", () => { | |||
| expect(reducer(undefined, setDoneProcess(false))).toEqual({ | |||
| doneProcess: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,32 @@ | |||
| import reducer from "../../../../store/reducers/processes/processesReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setProcesses, | |||
| setProcessesError, | |||
| } from "../../../../store/actions/processes/processesAction"; | |||
| import { mockState } from "../../../../mockState"; | |||
| describe("processes reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| processes: [], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setProcessesError("Error"))).toEqual({ | |||
| processes: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect( | |||
| reducer(undefined, setProcesses(mockState.patterns.processes)) | |||
| ).toEqual({ | |||
| processes: mockState.patterns.processes, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,66 @@ | |||
| import reducer from "../../../../store/reducers/processes/statusReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setStatuses, | |||
| setStatusesError, | |||
| changeStatusIsCheckedValue, | |||
| } from "../../../../store/actions/processes/statusAction"; | |||
| describe("status reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| statuses: [], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setStatusesError("Error"))).toEqual({ | |||
| statuses: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state success", () => { | |||
| expect(reducer(undefined, setStatuses(["option1", "option2"]))).toEqual({ | |||
| statuses: ["option1", "option2"], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should not change status because there is no option with name which we send as argument", async () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| statuses: [{ name: "option1" }, { name: "option2" }], | |||
| errorMessage: "", | |||
| }, | |||
| changeStatusIsCheckedValue("option3") | |||
| ) | |||
| ).toEqual({ | |||
| statuses: [{ name: "option1" }, { name: "option2" }], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should not change status because there is option with name which we send as argument", async () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| statuses: [ | |||
| { name: "option1", isChecked: false }, | |||
| { name: "option2", isChecked: false }, | |||
| ], | |||
| errorMessage: "", | |||
| }, | |||
| changeStatusIsCheckedValue("option1") | |||
| ) | |||
| ).toEqual({ | |||
| statuses: [ | |||
| { name: "option1", isChecked: true }, | |||
| { name: "option2", isChecked: false }, | |||
| ], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,37 @@ | |||
| import reducer from "../../../../store/reducers/processes/statusUpdateReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| setUpdateStatusReq, | |||
| setUpdateStatusSucc, | |||
| setUpdateStatusErr, | |||
| } from "../../../../store/actions/processes/processAction"; | |||
| describe("process reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| success: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setUpdateStatusErr("Error"))).toEqual({ | |||
| success: false, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the success to true", () => { | |||
| expect(reducer(undefined, setUpdateStatusSucc())).toEqual({ | |||
| success: true, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the success to false", () => { | |||
| expect(reducer(undefined, setUpdateStatusReq())).toEqual({ | |||
| success: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,22 @@ | |||
| import reducer from "../../../store/reducers/register/registerReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| registerError, | |||
| registerSuccess, | |||
| } from "../../../store/actions/register/registerActions"; | |||
| describe("register reducer", () => { | |||
| it("should set success", () => { | |||
| expect(reducer(undefined, registerSuccess())).toEqual({ | |||
| isSuccess: true, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set error", () => { | |||
| expect(reducer(undefined, registerError("Error"))).toEqual({ | |||
| isSuccess: false, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,22 @@ | |||
| import reducer from "../../../store/reducers/schedule/scheduleReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| fetchScheduleError, | |||
| fetchScheduleSuccess, | |||
| } from "../../../store/actions/schedule/scheduleActions"; | |||
| describe("schedule reducer", () => { | |||
| it("should set schedule", () => { | |||
| expect(reducer(undefined, fetchScheduleSuccess(["1", "2"]))).toEqual({ | |||
| schedule: ["1", "2"], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set error", () => { | |||
| expect(reducer(undefined, fetchScheduleError("Error"))).toEqual({ | |||
| schedule: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,21 @@ | |||
| import reducer from "../../../store/reducers/screeningTests/screeningTestsReducer"; | |||
| import expect from "expect"; | |||
| import { fetchScreeningTestsError, fetchScreeningTestsSuccess } from "../../../store/actions/screeningTests/screeningTestActions"; | |||
| describe("screening tests reducer", () => { | |||
| it("should set tests", () => { | |||
| expect( | |||
| reducer(undefined, fetchScreeningTestsSuccess(["test1", "test2"])) | |||
| ).toEqual({ | |||
| screeningTests: ["test1", "test2"], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set error", () => { | |||
| expect(reducer(undefined, fetchScreeningTestsError("Error"))).toEqual({ | |||
| screeningTests: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,29 @@ | |||
| import reducer from "../../../store/reducers/stats/statsReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| getStatsError, | |||
| getStatsSuccess, | |||
| } from "../../../store/actions/stats/statsActions"; | |||
| describe("stats reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| fetchStatsErrorMessage: "", | |||
| stats: {}, | |||
| }); | |||
| }); | |||
| it("should set error message", () => { | |||
| expect(reducer(undefined, getStatsError("Error"))).toEqual({ | |||
| stats: {}, | |||
| fetchStatsErrorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("Should set state stats", () => { | |||
| expect(reducer(undefined, getStatsSuccess({ data: "mockData" }))).toEqual({ | |||
| stats: { data: "mockData" }, | |||
| fetchStatsErrorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,34 @@ | |||
| import reducer from "../../../store/reducers/processes/statusUpdateReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| registerError, | |||
| registerSuccess, | |||
| } from "../../../store/actions/register/registerActions"; | |||
| import { | |||
| setUpdateStatusErr, | |||
| setUpdateStatusReq, | |||
| setUpdateStatusSucc, | |||
| } from "../../../store/actions/processes/processAction"; | |||
| describe("status update reducer", () => { | |||
| it("should set success", () => { | |||
| expect(reducer(undefined, setUpdateStatusSucc())).toEqual({ | |||
| success: true, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set error", () => { | |||
| expect(reducer(undefined, setUpdateStatusErr("Error"))).toEqual({ | |||
| success: false, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set error", () => { | |||
| expect(reducer(undefined, setUpdateStatusReq("any"))).toEqual({ | |||
| success: false, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,66 @@ | |||
| import reducer from "../../../store/reducers/technology/technologiesReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| changeIsCheckedValue, | |||
| resetIsCheckedValue, | |||
| setTechnologies, | |||
| setTechnologiesError, | |||
| } from "../../../store/actions/technologies/technologiesActions"; | |||
| describe("technologies reducer", () => { | |||
| it("should set techologies", () => { | |||
| expect(reducer(undefined, setTechnologies(["tech1", "tech2"]))).toEqual({ | |||
| technologies: ["tech1", "tech2"], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set error", () => { | |||
| expect(reducer(undefined, setTechnologiesError("Error"))).toEqual({ | |||
| technologies: [], | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should check tech", () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| technologies: [ | |||
| { id: 1, name: "T1", isChecked: false }, | |||
| { id: 2, name: "T2", isChecked: false }, | |||
| ], | |||
| errorMessage: "", | |||
| }, | |||
| changeIsCheckedValue("T1") | |||
| ) | |||
| ).toEqual({ | |||
| technologies: [ | |||
| { id: 1, name: "T1", isChecked: true }, | |||
| { id: 2, name: "T2", isChecked: false }, | |||
| ], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should reset checked techs", () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| technologies: [ | |||
| { id: 1, name: "T1", isChecked: true }, | |||
| { id: 2, name: "T2", isChecked: true }, | |||
| ], | |||
| errorMessage: "", | |||
| }, | |||
| resetIsCheckedValue("T1") | |||
| ) | |||
| ).toEqual({ | |||
| technologies: [ | |||
| { id: 1, name: "T1", isChecked: false }, | |||
| { id: 2, name: "T2", isChecked: false }, | |||
| ], | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,47 @@ | |||
| import reducer from "../../../store/reducers/user/userDetailsReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| stateUserDetailsSuccess, | |||
| toggleSingleUser, | |||
| userDetailsError, | |||
| } from "../../../store/actions/users/usersActions"; | |||
| describe("user reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| user: {}, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state user error", () => { | |||
| expect(reducer(undefined, userDetailsError("Error"))).toEqual({ | |||
| user: {}, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| it("should set the state user", () => { | |||
| expect( | |||
| reducer(undefined, stateUserDetailsSuccess({ name: "User" })) | |||
| ).toEqual({ | |||
| user: { name: "User" }, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| }); | |||
| it("should set the state user", () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| user: { name: "User", isEnabled: true }, | |||
| errorMessage: "", | |||
| }, | |||
| toggleSingleUser() | |||
| ) | |||
| ).toEqual({ | |||
| user: { name: "User", isEnabled: false }, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,46 @@ | |||
| import reducer from "../../../store/reducers/user/userReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| resetUserState, | |||
| setUser, | |||
| setUserError, | |||
| } from "../../../store/actions/user/userActions"; | |||
| describe("invite user reducer", () => { | |||
| it("should set the state user", () => { | |||
| expect(reducer(undefined, setUser({ username: "username" }))).toEqual({ | |||
| user: { | |||
| username: "username", | |||
| }, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should reset the state", () => { | |||
| expect(reducer(undefined, resetUserState())).toEqual({ | |||
| user: { | |||
| id: "", | |||
| firstName: "", | |||
| lastName: "", | |||
| username: "", | |||
| token: "", | |||
| refreshToken: "", | |||
| }, | |||
| errorMessage: "", | |||
| }); | |||
| }); | |||
| it("should set the state error", () => { | |||
| expect(reducer(undefined, setUserError('Error'))).toEqual({ | |||
| user: { | |||
| id: "", | |||
| firstName: "", | |||
| lastName: "", | |||
| username: "", | |||
| token: "", | |||
| refreshToken: "", | |||
| }, | |||
| errorMessage: "Error", | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,104 @@ | |||
| import reducer from "../../../store/reducers/user/usersReducer"; | |||
| import expect from "expect"; | |||
| import { | |||
| deleteStateUser, | |||
| deleteUserError, | |||
| setEnableUsers, | |||
| setEnableUsersError, | |||
| setUsers, | |||
| setUsersError, | |||
| } from "../../../store/actions/users/usersActions"; | |||
| describe("users reducer", () => { | |||
| it("should return the initial state", () => { | |||
| expect(reducer(undefined, {})).toEqual({ | |||
| fetchUsersErrorMessage: "", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "", | |||
| users: [], | |||
| }); | |||
| }); | |||
| it("should set error message", () => { | |||
| expect(reducer(undefined, setUsersError("Error"))).toEqual({ | |||
| fetchUsersErrorMessage: "Error", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "", | |||
| users: [], | |||
| }); | |||
| }); | |||
| it("Should set state users", () => { | |||
| expect(reducer(undefined, setUsers(["user1", "user2"]))).toEqual({ | |||
| fetchUsersErrorMessage: "", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "", | |||
| users: ["user1", "user2"], | |||
| }); | |||
| }); | |||
| it("should set enable toggle error message", () => { | |||
| expect(reducer(undefined, setEnableUsersError("Error"))).toEqual({ | |||
| fetchUsersErrorMessage: "", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "Error", | |||
| users: [], | |||
| }); | |||
| }); | |||
| it("should toogle enable on specific user", () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| fetchUsersErrorMessage: "", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "", | |||
| users: [ | |||
| { id: 1, name: "User1", isEnabled: true }, | |||
| { id: 2, name: "User2", isEnabled: true }, | |||
| ], | |||
| }, | |||
| setEnableUsers(1) | |||
| ) | |||
| ).toEqual({ | |||
| fetchUsersErrorMessage: "", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "", | |||
| users: [ | |||
| { id: 1, name: "User1", isEnabled: false }, | |||
| { id: 2, name: "User2", isEnabled: true }, | |||
| ], | |||
| }); | |||
| }); | |||
| it("should set delete user error message", () => { | |||
| expect(reducer(undefined, deleteUserError("Error"))).toEqual({ | |||
| fetchUsersErrorMessage: "", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "Error", | |||
| users: [], | |||
| }); | |||
| }); | |||
| it("should delete specific user", () => { | |||
| expect( | |||
| reducer( | |||
| { | |||
| fetchUsersErrorMessage: "", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "", | |||
| users: [ | |||
| { id: 1, name: "User1", isEnabled: true }, | |||
| { id: 2, name: "User2", isEnabled: true }, | |||
| ], | |||
| }, | |||
| deleteStateUser(1) | |||
| ) | |||
| ).toEqual({ | |||
| fetchUsersErrorMessage: "", | |||
| selected: {}, | |||
| toggleEnableErrorMessage: "", | |||
| users: [{ id: 2, name: "User2", isEnabled: true }], | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,106 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import * as api from "../../request/candidatesRequest"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { ADS_CANDIDATES_FETCH } from "../../store/actions/candidates/candidatesActionConstants"; | |||
| import { getAdsCandidates } from "../../store/saga/candidatesSaga"; | |||
| import { | |||
| fetchAdsCandidatesError, | |||
| fetchAdsCandidatesSuccess, | |||
| } from "../../store/actions/candidates/candidatesActions"; | |||
| import AdsCandidatesPage from "../../pages/CandidatesPage/AdsCandidatesPage"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("AdsCandidatesPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <AdsCandidatesPage search="" /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector | |||
| .mockReturnValueOnce(mockState.candidates.adsCandidates) | |||
| .mockReturnValueOnce(mockState.candidates.adsCandidates); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get adsCandidates request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: ADS_CANDIDATES_FETCH, | |||
| payload: { | |||
| currentPage: 0, | |||
| employmentType: "", | |||
| maxDateOfApplication: "", | |||
| maxExperience: 0, | |||
| minDateOfApplication: "", | |||
| minExperience: 0, | |||
| pageSize: 0, | |||
| technologies: [], | |||
| }, | |||
| }); | |||
| }); | |||
| it("should load and handle adsCandidates in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.candidates.adsCandidates }; | |||
| api.getFilteredAdsCandidates = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.candidates.adsCandidates, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getAdsCandidates, {}).done; | |||
| expect(api.getFilteredAdsCandidates.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| fetchAdsCandidatesSuccess(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("should handle adsCandidates load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => mockState.technologies.fetchTecnologiesErrorMessage); | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.technologies.fetchTecnologiesErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getFilteredAdsCandidates = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.candidates.adsCandidates, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getAdsCandidates, {}).done; | |||
| expect(api.getFilteredAdsCandidates.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| fetchAdsCandidatesError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,407 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import AdsPage from "../../pages/AdsPage/AdsPage"; | |||
| import * as api from "../../request/adsRequest"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { FETCH_ADS_REQ } from "../../store/actions/ads/adsActionConstants"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import * as fc from "../../store/saga/adsSaga"; | |||
| import { setAds, setFilteredAds } from "../../store/actions/ads/adsAction"; | |||
| import { setArchiveAds } from "../../store/actions/archiveAds/archiveAdsActions"; | |||
| import { setCreateAd } from "../../store/actions/createAd/createAdActions"; | |||
| import { setAd, setAdError } from "../../store/actions/ad/adActions"; | |||
| import { archiveActiveAd } from "../../store/actions/archiveActiveAd/archiveActiveAdActions"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("Ads reducer tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <AdsPage /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.ads); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get ads request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FETCH_ADS_REQ, | |||
| }); | |||
| }); | |||
| it("Should load and handle ads in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.ads.ads }; | |||
| api.getAllAds = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.getAds, {}).done; | |||
| expect(api.getAllAds.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setAds(mockedCall.data)); | |||
| }); | |||
| it("Should load and handle filtered ads in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const filter = { | |||
| minimumExperience: 0, | |||
| maximumExperience: 0, | |||
| technologies: [1], | |||
| workHour: "FullTime", | |||
| employmentType: "Work", | |||
| }; | |||
| const filteredData = mockState.ads.ads.filter( | |||
| (ad) => | |||
| ad.minimumExperience >= filter.minimumExperience && | |||
| ad.minimumExperience <= filter.maximumExperience && | |||
| ad.workHour === filter.workHour && | |||
| ad.employmentType === filter.employmentType | |||
| ); | |||
| const mockedCall = { data: filteredData }; | |||
| api.getAllFilteredAds = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.getFilteredAds, filter).done; | |||
| expect(api.getAllFilteredAds.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setFilteredAds(mockedCall.data)); | |||
| }); | |||
| it("Should load and handle archived ads in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const date = new Date(); | |||
| const filteredData = mockState.ads.ads.filter((ad) => ad.expiredAt < date); | |||
| const mockedCall = { data: filteredData }; | |||
| api.getAllArchiveAds = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.getArchiveAds, {}).done; | |||
| expect(api.getAllArchiveAds.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setArchiveAds(mockedCall.data)); | |||
| }); | |||
| it("Should load and handle ad by id in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const id = 1; | |||
| const filteredData = mockState.ads.ads.filter((ad) => ad.id === id); | |||
| const mockedCall = { data: filteredData }; | |||
| api.getAdDetailsById = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.getAd, { payload: id }).done; | |||
| expect(api.getAdDetailsById.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setAd(mockedCall.data)); | |||
| }); | |||
| it("Should create ad", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { | |||
| data: { | |||
| title: "React Developer", | |||
| minimumExperience: 1, | |||
| createdAt: new Date(), | |||
| expiredAt: new Date("2023-5-5"), | |||
| keyResponsibilities: "key responsibilities", | |||
| requirements: "requirements", | |||
| offer: "offer", | |||
| workHour: "PartTime", | |||
| employmentType: "Intership", | |||
| technologiesIds: [1, 2], | |||
| onSuccessAddAd: jest.fn, | |||
| }, | |||
| }; | |||
| api.createNewAd = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.createAd, { | |||
| payload: { | |||
| title: "React Developer", | |||
| minimumExperience: 1, | |||
| createdAt: new Date(), | |||
| expiredAt: new Date("2023-5-5"), | |||
| keyResponsibilities: "key responsibilities", | |||
| requirements: "requirements", | |||
| offer: "offer", | |||
| workHour: "PartTime", | |||
| employmentType: "Intership", | |||
| technologiesIds: [1, 2], | |||
| onSuccessAddAd: jest.fn, | |||
| }, | |||
| }).done; | |||
| expect(api.createNewAd.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setCreateAd(mockedCall.data)); | |||
| }); | |||
| it("Archive ad", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { | |||
| data: { | |||
| id: 1, | |||
| navigateToAds: jest.fn, | |||
| }, | |||
| }; | |||
| api.archiveActiveAdRequest = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.archiveActiveAdSaga, { | |||
| payload: { | |||
| id: 1, | |||
| navigateToAds: jest.fn, | |||
| }, | |||
| }).done; | |||
| expect(api.archiveActiveAdRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(archiveActiveAd(mockedCall.data)); | |||
| }); | |||
| it("Should not return ads when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.getAllAds = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.getAds, {}).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not return filtered ads when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| const filter = { | |||
| minimumExperience: 0, | |||
| maximumExperience: 0, | |||
| technologies: [1], | |||
| workHour: "FullTime", | |||
| employmentType: "Work", | |||
| }; | |||
| api.getFilteredAds = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.getFilteredAds, filter).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not return ad when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.getAd = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.getAd, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not return archived ad when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.getAd = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.getArchiveAds, {}).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not create ad when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.createNewAd = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.createAd, { | |||
| payload: { | |||
| title: "React Developer", | |||
| minimumExperience: 1, | |||
| createdAt: new Date(), | |||
| expiredAt: new Date("2023-5-5"), | |||
| keyResponsibilities: "key responsibilities", | |||
| requirements: "requirements", | |||
| offer: "offer", | |||
| workHour: "PartTime", | |||
| employmentType: "Intership", | |||
| technologiesIds: [1, 2], | |||
| onSuccessAddAd: jest.fn, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should archive active ad when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.createNewAd = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.archiveActiveAdSaga, { | |||
| payload: { | |||
| id: 1, | |||
| navigateToAds: jest.fn, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("should handle ad load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.getAd = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.ads.ads, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.getAd, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(api.getAdDetailsById.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setAdError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,103 @@ | |||
| import { runSaga } from "redux-saga"; | |||
| import * as api from "../../request/applicantRequest"; | |||
| import * as redux from "react-redux"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| import { applyForAd, applyForAdError } from "../../store/actions/applyForAd/applyForAdActions"; | |||
| import { applyForAdSaga } from "../../store/saga/applicantsSaga"; | |||
| describe("applicants tests saga tests", () => { | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce("anything"); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should handle applyForAdSaga saga with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: "Data" }; | |||
| api.applyForAdRequest = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn() | |||
| await runSaga(fakeStore, applyForAdSaga, { | |||
| payload: { | |||
| adId: "", | |||
| firstName: "", | |||
| lastName: "", | |||
| gender: "", | |||
| dateOfBirth: "", | |||
| phoneNumber: "", | |||
| professionalQualification: "", | |||
| technologiesIds: "", | |||
| experience: "", | |||
| linkedinLink: "", | |||
| githubLink: "", | |||
| bitBucketLink: "", | |||
| email: "", | |||
| coverLetter: "", | |||
| pdfFile: "", | |||
| handleApiResponseSuccess: mockfn | |||
| }, | |||
| }).done; | |||
| expect(api.applyForAdRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(applyForAd(mockedCall.data)); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| }); | |||
| it("Should handle apply for ad saga with errors", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| const mockedCall = { response: { data: { message: "Error" } } }; | |||
| api.applyForAdRequest = jest.fn(() => Promise.reject(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, applyForAdSaga, { | |||
| payload: { | |||
| adId: "", | |||
| firstName: "", | |||
| lastName: "", | |||
| gender: "", | |||
| dateOfBirth: "", | |||
| phoneNumber: "", | |||
| professionalQualification: "", | |||
| technologiesIds: "", | |||
| experience: "", | |||
| linkedinLink: "", | |||
| githubLink: "", | |||
| bitBucketLink: "", | |||
| email: "", | |||
| coverLetter: "", | |||
| pdfFile: "", | |||
| }, | |||
| }).done; | |||
| expect(api.applyForAdRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(applyForAdError("Error")); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,182 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import * as api from "../../request/candidatesRequest"; | |||
| import * as api2 from '../../request/usersRequest'; | |||
| import { runSaga } from "redux-saga"; | |||
| import { CANDIDATE_FETCH } from "../../store/actions/candidate/candidateActionConstants"; | |||
| import { FETCH_USERS_REQ } from "../../store/actions/users/usersActionConstants"; | |||
| import { getSingleCandidate } from "../../store/saga/candidatesSaga"; | |||
| import {getUsers} from '../../store/saga/usersSaga' | |||
| import { | |||
| fetchCandidateSuccess, | |||
| fetchCandidateError, | |||
| } from "../../store/actions/candidate/candidateActions"; | |||
| import { | |||
| setUsers, | |||
| setUsersError | |||
| } from "../../store/actions/users/usersActions"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| import CandidateDetailsPage from "../../pages/CandidatesPage/CandidateDetailsPage"; | |||
| const mockHistoryPush = jest.fn(); | |||
| // mock param which we send as part of URL | |||
| jest.mock("react-router-dom", () => ({ | |||
| ...jest.requireActual("react-router-dom"), | |||
| useHistory: () => ({ | |||
| push: mockHistoryPush, | |||
| }), | |||
| useParams: () => ({ | |||
| id: 1, | |||
| }), | |||
| })); | |||
| describe("CandidateDetailsPage render tests", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "", | |||
| }, | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <CandidateDetailsPage {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector | |||
| .mockReturnValueOnce(mockState.users.users) | |||
| .mockReturnValueOnce(mockState.users.user) | |||
| .mockReturnValueOnce(mockState.candidate.candidate); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch fetch candidate request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| payload: { id: 1 }, | |||
| type: CANDIDATE_FETCH, | |||
| }); | |||
| }); | |||
| it("Should dispatch fetch users request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FETCH_USERS_REQ, | |||
| }); | |||
| }); | |||
| it("should load and handle candidate in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.candidate.candidate }; | |||
| api.getCandidate = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.candidate.candidate, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getSingleCandidate, { payload: { id: 1 } }).done; | |||
| expect(api.getCandidate.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| fetchCandidateSuccess(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("should load and handle users in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.users.users }; | |||
| api2.getAllUsers = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getUsers).done; | |||
| expect(api2.getAllUsers.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setUsers(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("should handle candidate load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn( | |||
| () => mockState.candidate.fetchCandidateErrorMessage | |||
| ); | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.candidate.fetchCandidateErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getCandidate = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.candidate.candidate, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getSingleCandidate, { payload: { id: 1 } }).done; | |||
| expect(api.getCandidate.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| fetchCandidateError(error.response.data.message) | |||
| ); | |||
| }); | |||
| it("should handle users load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn( | |||
| () => mockState.users.fetchUsersErrorMessage | |||
| ); | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.users.fetchUsersErrorMessage }, | |||
| }, | |||
| }; | |||
| api2.getAllUsers = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getUsers).done; | |||
| expect(api2.getAllUsers.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setUsersError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,91 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import CandidatesPage from "../../pages/CandidatesPage/CandidatesPage"; | |||
| import * as api from "../../request/technologiesRequest"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { FETCH_TECHNOLOGIES_REQ } from "../../store/actions/technologies/technologiesActionConstants"; | |||
| import { getTechnologies } from "../../store/saga/technologiesSaga"; | |||
| import { | |||
| setTechnologies, | |||
| setTechnologiesError, | |||
| } from "../../store/actions/technologies/technologiesActions"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("CandidatesPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <CandidatesPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.technologies.technologies); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get technologies request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FETCH_TECHNOLOGIES_REQ, | |||
| }); | |||
| }); | |||
| it("should load and handle techonologies in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.technologies.technologies }; | |||
| api.getAllTechnologies = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.technologies.technologies, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getTechnologies).done; | |||
| expect(api.getAllTechnologies.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setTechnologies(mockedCall.data)); | |||
| }); | |||
| it("should handle technologies load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => mockState.candidates.fetchCandidatesErrorMessage); | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.candidates.fetchCandidatesErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getAllTechnologies = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.technologies.technologies, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getTechnologies).done; | |||
| expect(api.getAllTechnologies.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setTechnologiesError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,407 @@ | |||
| import * as redux from "react-redux"; | |||
| import { mockState } from "../../mockState"; | |||
| import * as api from "../../request/candidatesRequest"; | |||
| import { | |||
| filterCandidatesError, | |||
| filterCandidatesSuccess, | |||
| fetchCandidateOptionsSuccess, | |||
| fetchCandidateOptionsError, | |||
| fetchInitProcessError, | |||
| fetchInitProcessSuccess, | |||
| } from "../../store/actions/candidates/candidatesActions"; | |||
| import { | |||
| fetchCandidateError, | |||
| fetchCandidateSuccess, | |||
| deleteCandidateError, | |||
| deleteCandidateSuccess, | |||
| createCandidateComment, | |||
| createCandidateCommentError, | |||
| createCandidateCommentSuccess, | |||
| } from "../../store/actions/candidate/candidateActions"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { | |||
| filterCandidates as k, | |||
| getSingleCandidate, | |||
| deleteSingleCandidate, | |||
| getOptions, | |||
| initializeProcess, | |||
| addComment, | |||
| } from "../../store/saga/candidatesSaga"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("candidatesSaga reducer tests", () => { | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.candidates.candidates); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| // filterCandidates | |||
| it("should run filterCandidates saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.getFilteredCandidates = jest.fn(() => Promise.resolve({})); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, k, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.getFilteredCandidates.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(filterCandidatesSuccess()); | |||
| }); | |||
| it("should call handleApiResponseSuccess inside filterCandidates saga function", async () => { | |||
| const dispatchedActions = []; | |||
| api.getFilteredCandidates = jest.fn(() => Promise.resolve({})); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockFn = jest.fn(); | |||
| await runSaga(fakeStore, k, { | |||
| payload: { | |||
| data: {}, | |||
| handleApiResponseSuccess: mockFn, | |||
| }, | |||
| }).done; | |||
| expect(mockFn).toHaveBeenCalled(); | |||
| }); | |||
| it("should handle error inside filterCandidates saga function", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { response: { data: { message: "Error" } } }; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| api.getFilteredCandidates = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, k, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.getFilteredCandidates.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(filterCandidatesError("Error")); | |||
| }); | |||
| // getSingleCandidate | |||
| it("should run getSingleCandidate saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.getCandidate = jest.fn(() => Promise.resolve({})); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getSingleCandidate, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.getCandidate.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(fetchCandidateSuccess()); | |||
| }); | |||
| it("should handle error inside getSingleCandidate saga function", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { response: { data: { message: "Error" } } }; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| api.getCandidate = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getSingleCandidate, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.getCandidate.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(fetchCandidateError("Error")); | |||
| }); | |||
| // addComment | |||
| // it("should run addComment saga function with actions", async () => { | |||
| // const dispatchedActions = []; | |||
| // api.createComment = jest.fn(() => | |||
| // Promise.resolve({ payload: { user: {} } }) | |||
| // ); | |||
| // const fakeStore = { | |||
| // getState: () => ({ | |||
| // isSuccess: false, | |||
| // errorMessage: "", | |||
| // }), | |||
| // dispatch: (action) => dispatchedActions.push(action), | |||
| // }; | |||
| // await runSaga(fakeStore, addComment, { | |||
| // payload: { user: {} }, | |||
| // }).done; | |||
| // expect(api.createComment.mock.calls.length).toBe(1); | |||
| // expect(dispatchedActions).toContainEqual(createCandidateCommentSuccess()); | |||
| // }); | |||
| it("should handle error inside getSingleCandidate saga function", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { response: { data: { message: "Error" } } }; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| api.createComment = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, addComment, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.createComment.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| createCandidateCommentError("Error") | |||
| ); | |||
| }); | |||
| // deleteSingleCandidate | |||
| it("should run deleteSingleCandidate saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.deleteCandidate = jest.fn(() => Promise.resolve({})); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, deleteSingleCandidate, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.deleteCandidate.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(deleteCandidateSuccess()); | |||
| }); | |||
| it("should call handleApiResponseSuccess inside filterCandidates saga function", async () => { | |||
| const dispatchedActions = []; | |||
| api.deleteCandidate = jest.fn(() => Promise.resolve({})); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockFn = jest.fn(); | |||
| await runSaga(fakeStore, deleteSingleCandidate, { | |||
| payload: { | |||
| data: {}, | |||
| handleApiResponseSuccess: mockFn, | |||
| }, | |||
| }).done; | |||
| expect(mockFn).toHaveBeenCalled(); | |||
| }); | |||
| it("should handle error inside deleteSingleCandidate saga function", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { response: { data: { message: "Error" } } }; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| api.deleteCandidate = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, deleteSingleCandidate, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.deleteCandidate.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(deleteCandidateError("Error")); | |||
| }); | |||
| // getOptions | |||
| it("should run getOptions saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.getCandidateOptions = jest.fn(() => Promise.resolve({})); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getOptions, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.getCandidateOptions.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(fetchCandidateOptionsSuccess()); | |||
| }); | |||
| it("should handle error inside getOptions saga function", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { response: { data: { message: "Error" } } }; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| api.getCandidateOptions = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getOptions, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.getCandidateOptions.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| fetchCandidateOptionsError("Error") | |||
| ); | |||
| }); | |||
| // initializeProcess | |||
| it("should run initializeProcess saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.initializeProcessRequest = jest.fn(() => Promise.resolve({})); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, initializeProcess, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.initializeProcessRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(fetchInitProcessSuccess()); | |||
| }); | |||
| it("should handle error inside initializeProcess saga function", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { response: { data: { message: "Error" } } }; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| api.initializeProcessRequest = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, initializeProcess, { | |||
| payload: { | |||
| data: {}, | |||
| }, | |||
| }).done; | |||
| expect(api.initializeProcessRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(fetchInitProcessError("Error")); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,245 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { fireEvent, render, screen, waitFor } from "@testing-library/react"; | |||
| import UsersPage from "../../pages/UsersPage/UsersPage"; | |||
| import * as api from "../../request/usersRequest"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { FETCH_USERS_REQ } from "../../store/actions/users/usersActionConstants"; | |||
| import { setUsersError } from "../../store/actions/users/usersActions"; | |||
| import { getUsers, invite } from "../../store/saga/usersSaga"; | |||
| import InviteDialog from "../../components/MUI/InviteDialog"; | |||
| import * as userReqs from "../../store/actions/users/usersActions"; | |||
| import { | |||
| inviteUserSuccess, | |||
| inviteUserError, | |||
| } from "../../store/actions/users/usersActions"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| const props = { | |||
| title: "Any", | |||
| subtitle: "Any", | |||
| imgSrc: "Any", | |||
| open: true, | |||
| onClose: jest.fn(), | |||
| maxWidth: "lg", | |||
| fullWidth: true, | |||
| responsive: true, | |||
| }; | |||
| describe("invite dialog reducer tests onSuccess", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <InviteDialog {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| let spyHelper; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue({ | |||
| invite: { | |||
| isSuccess: true, | |||
| errorMessage: "", | |||
| }, | |||
| }); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValueOnce(mockDispatch); | |||
| // Mock rejectErrorCodeHelper | |||
| spyHelper = jest.spyOn(helper, "rejectErrorCodeHelper") | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should call onClose if success", () => { | |||
| render(cont); | |||
| expect(props.onClose).toHaveBeenCalled(); | |||
| }); | |||
| }); | |||
| describe("invite reducer tests default", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <InviteDialog {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue({ | |||
| invite: { | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }, | |||
| }); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch invite action after submit", async () => { | |||
| render(cont); | |||
| // get inputs | |||
| var input = screen.getAllByTestId("invite-input-text"); | |||
| // trigger onChange event handler | |||
| fireEvent.change(input[0], { target: { value: "Firstname" } }); | |||
| fireEvent.change(input[1], { target: { value: "Lastname" } }); | |||
| fireEvent.change(input[2], { target: { value: "admin@dilig.net" } }); | |||
| // get submit button and fire click event | |||
| var submitBtn = screen.getAllByRole("button")[0]; | |||
| fireEvent.click(submitBtn); | |||
| // or get form and fire submit event | |||
| // var form = screen.getByTestId("invite-form"); | |||
| // fireEvent.submit(form) | |||
| // we need waitFor because we await formik to validate our form | |||
| // another way to check form submission is if the submitHandler is | |||
| // a prop | |||
| await waitFor(() => expect(mockDispatch).toHaveBeenCalled()); | |||
| }); | |||
| it("should run inviteUser saga function with actions", 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), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, invite, { | |||
| payload: { | |||
| firstName: "st", | |||
| lastName: "Test", | |||
| email: "test@dilig.net", | |||
| }, | |||
| }).done; | |||
| expect(api.inviteUserRequest.mock.calls.length).toBe(1); | |||
| 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 = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(()=> 'Server error') | |||
| // 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 mockError = { | |||
| response: { | |||
| data: { message: "Server error" }, | |||
| }, | |||
| }; | |||
| api.inviteUserRequest = jest.fn(() => Promise.reject(mockError)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| invite: { | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }, | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, invite, { | |||
| payload: { | |||
| firstName: "st", | |||
| lastName: "Test", | |||
| email: "test@dilig.net", | |||
| }, | |||
| }).done; | |||
| expect(api.inviteUserRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| inviteUserError("Server error") | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,478 @@ | |||
| import * as redux from "react-redux"; | |||
| import { mockState } from "../../mockState"; | |||
| import * as api from "../../request/loginRequest"; | |||
| import * as authHelper from "../../util/helpers/authScopeHelpers"; | |||
| import * as reqHelper from "../../request"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { | |||
| fetchGoogleUserSuccess, | |||
| fetchUserError, | |||
| fetchUserSuccess, | |||
| forgetPasswordSuccess, | |||
| resetLoginState, | |||
| } from "../../store/actions/login/loginActions"; | |||
| import jwt from "jsonwebtoken"; | |||
| import { | |||
| authenticateUser, | |||
| fetchGoogleUser, | |||
| fetchUser, | |||
| forgetPassword, | |||
| resetPassword, | |||
| logoutUser, | |||
| refreshToken as ref, | |||
| generateToken, | |||
| } from "../../store/saga/loginSaga"; | |||
| import { setUser } from "../../store/actions/user/userActions"; | |||
| import { BASE_PAGE } from "../../constants/pages"; | |||
| import history from "../../store/utils/history"; | |||
| describe("Login Saga reducer tests", () => { | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.user.user); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("should run fetchUser saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: { token: "token", refreshToken: "token" } }; | |||
| api.attemptLogin = jest.fn(() => Promise.resolve(res)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| await runSaga(fakeStore, fetchUser, { | |||
| payload: { | |||
| password: "pass", | |||
| username: "username", | |||
| handleApiResponseSuccess: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.attemptLogin.mock.calls.length).toBe(1); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(fetchUserSuccess(res.data)); | |||
| expect(dispatchedActions).toContainEqual(setUser(res.data)); | |||
| }); | |||
| it("should handle fetchUser saga error with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { response: { data: { message: "Error" } } }; | |||
| api.attemptLogin = jest.fn(() => Promise.reject(res)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| await runSaga(fakeStore, fetchUser, { | |||
| payload: { | |||
| password: "pass", | |||
| username: "username", | |||
| handleApiResponseFailed: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.attemptLogin.mock.calls.length).toBe(1); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(fetchUserError(res.data)); | |||
| }); | |||
| it("should run forgetPassword saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: {} }; | |||
| api.forgetPasswordEmailSend = jest.fn(() => Promise.resolve(res)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| await runSaga(fakeStore, forgetPassword, { | |||
| payload: { | |||
| email: "email", | |||
| handleApiResponseSuccess: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.forgetPasswordEmailSend.mock.calls.length).toBe(1); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(forgetPasswordSuccess(res.data)); | |||
| }); | |||
| it("should handle forgetPassword saga error with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { response: { data: { message: "Error" } } }; | |||
| api.forgetPasswordEmailSend = jest.fn(() => Promise.reject(res)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| await runSaga(fakeStore, forgetPassword, { | |||
| payload: { | |||
| password: "pass", | |||
| username: "username", | |||
| handleApiResponseFailed: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.forgetPasswordEmailSend.mock.calls.length).toBe(1); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(fetchUserError(res.data)); | |||
| }); | |||
| it("should run reset password saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: {} }; | |||
| api.sendResetPassword = jest.fn(() => Promise.resolve(res)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| await runSaga(fakeStore, resetPassword, { | |||
| payload: { | |||
| code: "code", | |||
| email: "mail", | |||
| password: "password", | |||
| handleApiResponseSuccess: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.sendResetPassword.mock.calls.length).toBe(1); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(forgetPasswordSuccess(res.data)); | |||
| }); | |||
| it("should handle forgetPassword saga error with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { response: { data: { message: "Error" } } }; | |||
| api.sendResetPassword = jest.fn(() => Promise.reject(res)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| await runSaga(fakeStore, resetPassword, { | |||
| payload: { | |||
| code: "code", | |||
| email: "mail", | |||
| password: "password", | |||
| handleApiResponseFailed: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.sendResetPassword.mock.calls.length).toBe(1); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(fetchUserError(res.data)); | |||
| }); | |||
| it("should run fetch google user saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: { token: "token" } }; | |||
| api.attemptGoogleLogin = jest.fn(() => Promise.resolve(res)); | |||
| authHelper.authScopeSetHelper = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| await runSaga(fakeStore, fetchGoogleUser, { | |||
| payload: { | |||
| user: "mail", | |||
| token: "token", | |||
| handleApiResponseSuccess: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.attemptGoogleLogin.mock.calls.length).toBe(1); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| expect(authHelper.authScopeSetHelper).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(fetchGoogleUserSuccess(res.data)); | |||
| expect(dispatchedActions).toContainEqual({ | |||
| payload: { token: "token" }, | |||
| type: "[SUCCESS]LOGIN_GOOGLE_USER", | |||
| }); | |||
| }); | |||
| it("should handle fetch google error with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { response: { data: { message: "Error" } } }; | |||
| api.attemptGoogleLogin = jest.fn(() => Promise.reject(res)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| await runSaga(fakeStore, fetchGoogleUser, { | |||
| payload: { | |||
| user: "mail", | |||
| token: "token", | |||
| handleApiResponseFailed: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.attemptGoogleLogin.mock.calls.length).toBe(1); | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(fetchUserError(res.data)); | |||
| }); | |||
| it("should run authenticate user saga function with actions if token does not exist", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: { token: null } }; | |||
| api.attemptGoogleLogin = jest.fn(() => Promise.resolve(res)); | |||
| authHelper.authScopeStringGetHelper = jest.fn(() => ""); | |||
| const mockHistoryPush = jest.fn(); | |||
| history.push = mockHistoryPush; | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, authenticateUser).done; | |||
| expect(mockHistoryPush).toHaveBeenCalledWith(BASE_PAGE); | |||
| expect(dispatchedActions).not.toContainEqual( | |||
| fetchUserSuccess(res.data.token) | |||
| ); | |||
| }); | |||
| it("should run authenticate user saga function with actions if token exists", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: { token: "token" } }; | |||
| api.attemptGoogleLogin = jest.fn(() => Promise.resolve(res)); | |||
| authHelper.authScopeStringGetHelper = jest.fn(() => "token"); | |||
| const mockHistoryPush = jest.fn(); | |||
| history.push = mockHistoryPush; | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, authenticateUser).done; | |||
| expect(mockHistoryPush).not.toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual({ | |||
| payload: { JwtToken: "token" }, | |||
| type: "[SUCCESS]LOGIN_USER", | |||
| }); | |||
| }); | |||
| it("should run authenticate user saga function and handle errors", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { response: { data: { message: "message" } } }; | |||
| authHelper.authScopeStringGetHelper = jest.fn(() => Promise.reject(res)); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, authenticateUser).done; | |||
| expect(dispatchedActions).toContainEqual({ | |||
| // undefined because we have not mocked rejectCodeHelper | |||
| payload: undefined, | |||
| type: "[ERROR]LOGIN_USER", | |||
| }); | |||
| }); | |||
| it("should run logout user saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: { token: "token" } }; | |||
| // simply mock it to ensure we can test if method has been called | |||
| api.logoutUserRequest = jest.fn(() => Promise.resolve(res)); | |||
| authHelper.authScopeStringGetHelper = jest.fn(() => "token"); | |||
| authHelper.authScopeClearHelper = jest.fn(); | |||
| reqHelper.removeHeaderToken = jest.fn(); | |||
| const mockUser = { id: 1 }; | |||
| jwt.decode = jest.fn(() => mockUser); | |||
| const mockHistoryReplace = jest.fn(); | |||
| history.replace = mockHistoryReplace; | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, logoutUser).done; | |||
| expect(mockHistoryReplace).toHaveBeenCalled(); | |||
| expect(authHelper.authScopeClearHelper).toHaveBeenCalled(); | |||
| expect(reqHelper.removeHeaderToken).toHaveBeenCalled(); | |||
| expect(api.logoutUserRequest).toHaveBeenCalledWith(mockUser.id); | |||
| expect(dispatchedActions).toContainEqual(resetLoginState()); | |||
| }); | |||
| it("should run refreshToken saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: { user: "user", token: "token" } }; | |||
| api.refreshTokenRequest = jest.fn(() => Promise.resolve(res)); | |||
| authHelper.authScopeStringGetHelper = jest.fn(); | |||
| authHelper.authScopeStringGetHelper | |||
| .mockReturnValueOnce("Token") | |||
| .mockReturnValueOnce("RefreshToken"); | |||
| authHelper.authScopeSetHelper = jest.fn(); | |||
| reqHelper.addHeaderToken = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, ref).done; | |||
| expect(authHelper.authScopeStringGetHelper).toHaveBeenCalled(); | |||
| expect(api.refreshTokenRequest).toHaveBeenCalledWith({ | |||
| refreshToken: "RefreshToken", | |||
| token: "Token", | |||
| }); | |||
| }); | |||
| it("should run generateToken saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const res = { data: { JwtToken: "jwt", JwtRefreshToken: "refresh" } }; | |||
| api.generateTokenRequest = jest.fn(() => Promise.resolve(res)); | |||
| authHelper.authScopeSetHelper = jest.fn(); | |||
| authHelper.authScopeStringGetHelper = jest.fn(); | |||
| authHelper.authScopeStringGetHelper | |||
| .mockReturnValueOnce("Token") | |||
| .mockReturnValueOnce("RefreshToken"); | |||
| reqHelper.addHeaderToken = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| email: "", | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| var mockSession = jest.fn(); | |||
| Storage.prototype.setItem = mockSession; | |||
| const mockUser = { id: 1 }; | |||
| jwt.decode = jest.fn(() => mockUser); | |||
| const mockSuccess = jest.fn() | |||
| await runSaga(fakeStore, generateToken, { | |||
| payload: { | |||
| data: { data: "data" }, | |||
| impersonate: { data: "data" }, | |||
| registration: { data: "data" }, | |||
| onSuccess: mockSuccess | |||
| }, | |||
| }).done; | |||
| expect(authHelper.authScopeSetHelper).toHaveBeenCalled(); | |||
| expect(mockSession).toHaveBeenCalled(); | |||
| expect(mockSuccess).toHaveBeenCalled(); | |||
| expect(dispatchedActions).toContainEqual(setUser(mockUser)); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,431 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import PatternsPage from "../../pages/PatternsPage/PatternsPage"; | |||
| import * as api from "../../request/patternsRequest"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { FETCH_PATTERNS_REQ } from "../../store/actions/patterns/patternsActionConstants"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import * as fc from "../../store/saga/patternsSaga"; | |||
| import { | |||
| setFilteredPatterns, | |||
| setPatterns, | |||
| } from "../../store/actions/patterns/patternsActions"; | |||
| import { setPattern } from "../../store/actions/pattern/patternActions"; | |||
| import { setPatternApplicants } from "../../store/actions/patternApplicants/patternApplicantsActions"; | |||
| import { createPattern } from "../../store/actions/createPattern/createPatternActions"; | |||
| import { updatePattern } from "../../store/actions/updatePattern/updatePatternActions"; | |||
| import { scheduleAppointment } from "../../store/actions/scheduleAppointment/scheduleAppointmentActions"; | |||
| describe("Patterns reducer tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <PatternsPage /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.patterns); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get patterns request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FETCH_PATTERNS_REQ, | |||
| }); | |||
| }); | |||
| it("Should load and handle patterns in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.patterns.patterns }; | |||
| api.getAllPatterns = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.getPatterns, {}).done; | |||
| expect(api.getAllPatterns.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setPatterns(mockedCall.data)); | |||
| }); | |||
| it("Should load and handle pattern by id in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const id = 1; | |||
| const filteredData = mockState.patterns.patterns.filter( | |||
| (pattern) => pattern.id === id | |||
| ); | |||
| const mockedCall = { data: filteredData }; | |||
| api.getPatternById = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.getPattern, { payload: id }).done; | |||
| expect(api.getPatternById.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setPattern(mockedCall.data)); | |||
| }); | |||
| it("Should load and handle pattern applicants in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const id = 1; | |||
| const filteredData = mockState.patterns.patterns.filter( | |||
| (pattern) => pattern.id === id | |||
| ); | |||
| const mockedCall = { | |||
| data: { | |||
| ...filteredData[0].selectionLevel.selectionProcesses[0].applicant, | |||
| }, | |||
| }; | |||
| api.getPatternApplicantsById = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.getPatternApplicants, { payload: id }).done; | |||
| expect(api.getPatternApplicantsById.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setPatternApplicants(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("Should load and handle filtered patterns in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const filters = { | |||
| fromDate: new Date("2-2-2021"), | |||
| toDate: new Date("3-3-2023"), | |||
| selectionLevels: [1, 2], | |||
| }; | |||
| const filteredData = mockState.patterns.patterns.filter( | |||
| (pattern) => | |||
| pattern.createdAt >= filters.fromDate && | |||
| pattern.createdAt <= filters.toDate | |||
| ); | |||
| const mockedCall = { | |||
| data: filteredData, | |||
| }; | |||
| api.getFilteredPatterns = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.filterPatterns, filters).done; | |||
| expect(api.getFilteredPatterns.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setFilteredPatterns(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("Should create new pattern", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { | |||
| data: { | |||
| title: "Neuspesan korak", | |||
| selectionLevelId: 1, | |||
| message: "Poruka", | |||
| }, | |||
| }; | |||
| api.createPatternRequest = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.createPatternSaga, { | |||
| payload: { | |||
| title: "Neuspesan korak", | |||
| selectionLevelId: 1, | |||
| message: "Poruka", | |||
| }, | |||
| }).done; | |||
| expect(api.createPatternRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(createPattern(mockedCall.data)); | |||
| }); | |||
| it("Should update pattern", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { | |||
| data: { | |||
| id: 1, | |||
| title: "Zakazan intervju", | |||
| createdAt: new Date(), | |||
| selectionLevelId: 1, | |||
| message: "Message", | |||
| }, | |||
| }; | |||
| api.updatePatternRequest = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.updatePatternSaga, { | |||
| payload: { | |||
| id: 1, | |||
| title: "Zakazan intervju", | |||
| createdAt: new Date(), | |||
| selectionLevelId: 1, | |||
| message: "Message", | |||
| }, | |||
| }).done; | |||
| expect(api.updatePatternRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(updatePattern(mockedCall.data)); | |||
| }); | |||
| it("Should schedule appointment", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { | |||
| data: { | |||
| emails: ["ermin.bronja@dilig.net"], | |||
| patternId: 1, | |||
| handleApiResponseSuccess: jest.fn, | |||
| }, | |||
| }; | |||
| api.scheduleAppointmentRequest = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.scheduleAppointmentSaga, { | |||
| payload: { | |||
| emails: ["ermin.bronja@dilig.net"], | |||
| patternId: 1, | |||
| handleApiResponseSuccess: jest.fn, | |||
| }, | |||
| }).done; | |||
| expect(api.scheduleAppointmentRequest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| scheduleAppointment(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("Should not return patterns when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.getAllPatterns = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.getPatterns, {}).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not return pattern when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.getPatternById = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.getPattern, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not return pattern applicants when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.getPatternApplicants = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.getPatternApplicants, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not return filtered patterns when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.getFilteredPatterns = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.filterPatterns, { | |||
| fromDate: new Date("2-2-2021"), | |||
| toDate: new Date("3-3-2023"), | |||
| selectionLevels: [1, 2], | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not create pattern when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.createPatternRequest = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.createPatternSaga, { | |||
| payload: { | |||
| title: "Neuspesan korak", | |||
| selectionLevelId: 1, | |||
| message: "Poruka", | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not update pattern when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.updatePatternRequest = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.updatePatternSaga, { | |||
| payload: { | |||
| id: 1, | |||
| title: "Zakazan intervju", | |||
| createdAt: new Date(), | |||
| selectionLevelId: 1, | |||
| message: "Message", | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("Should not chedule appointment when exception was thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: "Error" }, | |||
| }, | |||
| }; | |||
| api.scheduleAppointmentRequest = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.patterns.patterns, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, fc.scheduleAppointmentSaga, { | |||
| payload: { | |||
| emails: ["ermin.bronja@dilig.net"], | |||
| patternId: 1, | |||
| handleApiResponseSuccess: jest.fn, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,566 @@ | |||
| import { runSaga } from "redux-saga"; | |||
| import * as api from "../../request/processesReguest"; | |||
| import { render } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import SelectionProcessPage from "../../pages/selectionProcessPage/selectionProcessPage"; | |||
| ("../../pages/SelectionProcessPage/SelectionProcessPage"); | |||
| import store from "../../store"; | |||
| import "../../i18n"; | |||
| import { mockState } from "../../mockState"; | |||
| import { FETCH_PROCESSES_REQ } from "../../store/actions/processes/processesActionConstants"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { | |||
| getProcesses, | |||
| getFilteredProcesses, | |||
| finishProcess, | |||
| changeStatus, | |||
| changeInterviewer, | |||
| getApplicantProcesses, | |||
| } from "../../store/saga/processSaga"; | |||
| import { | |||
| setProcesses, | |||
| setProcessesError, | |||
| } from "../../store/actions/processes/processesAction"; | |||
| import { SelectionProvider } from "../../context/SelectionContext"; | |||
| import { | |||
| setDoneProcess, | |||
| setDoneProcessError, | |||
| setUpdateInterviewerErr, | |||
| setUpdateInterviewerSucc, | |||
| setUpdateStatusErr, | |||
| setUpdateStatusSucc, | |||
| } from "../../store/actions/processes/processAction"; | |||
| import { | |||
| setApplicant, | |||
| setApplicantError, | |||
| } from "../../store/actions/processes/applicantAction"; | |||
| describe("SelectionProcessPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <SelectionProvider> | |||
| <Router history={history}> | |||
| <SelectionProcessPage /> | |||
| </Router> | |||
| </SelectionProvider> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector | |||
| .mockReturnValueOnce(mockState.selections) | |||
| .mockReturnValueOnce(mockState.selections.processes) | |||
| .mockReturnValueOnce(mockState.selections.statuses); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get processes request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FETCH_PROCESSES_REQ, | |||
| }); | |||
| }); | |||
| it("should load and handle levels with processes in case of success", async () => { | |||
| // we push all dispatched actions to make assertions easier | |||
| // and our tests less brittle | |||
| 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: mockState.selections.processes }; | |||
| api.getAllLevels = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, getProcesses).done; | |||
| expect(api.getAllLevels.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setProcesses(mockedCall.data)); | |||
| }); | |||
| it("should handle processes load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| // we simulate an error by rejecting the promise | |||
| // then we assert if our saga dispatched the action(s) correctly | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getAllLevels = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getProcesses).done; | |||
| expect(api.getAllLevels.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setProcessesError(error.response.data.message) | |||
| ); | |||
| }); | |||
| it("should load and handle levels with filtered processes in case of success", async () => { | |||
| // we push all dispatched actions to make assertions easier | |||
| // and our tests less brittle | |||
| const dispatchedActions = []; | |||
| const filter = { | |||
| statuses: ["Zakazan", "Odrađen"], | |||
| dateStart: new Date(2023, 0, 5), | |||
| dateEnd: new Date(2024, 1, 1), | |||
| }; | |||
| const filteredData = []; | |||
| mockState.selections.processes.forEach((level) => { | |||
| const filteredLevel = level; | |||
| filteredLevel.selectionProcesses = level.selectionProcesses.filter( | |||
| (v) => | |||
| v.date >= filter.dateStart && | |||
| v.date <= filter.dateEnd && | |||
| filter.statuses.includes(v.status) | |||
| ); | |||
| filteredData.push(filteredLevel); | |||
| }); | |||
| // 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: filteredData }; | |||
| api.getAllFilteredProcessesReq = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, getFilteredProcesses, filter).done; | |||
| expect(api.getAllFilteredProcessesReq.mock.calls.length).toBe(1); | |||
| 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 | |||
| const dispatchedActions = []; | |||
| const filter = { | |||
| statuses: ["Zakazan", "Odrađen"], | |||
| dateStart: new Date(2023, 0, 5), | |||
| dateEnd: new Date(2024, 1, 1), | |||
| }; | |||
| const filteredData = []; | |||
| mockState.selections.processes.forEach((level) => { | |||
| const filteredLevel = level; | |||
| filteredLevel.selectionProcesses = level.selectionProcesses.filter( | |||
| (v) => | |||
| v.date >= filter.dateStart && | |||
| v.date <= filter.dateEnd && | |||
| filter.statuses.includes(v.status) | |||
| ); | |||
| filteredData.push(filteredLevel); | |||
| }); | |||
| // 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: filteredData }; | |||
| api.getAllFilteredProcessesReq = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, getFilteredProcesses, filter).done; | |||
| expect(api.getAllFilteredProcessesReq.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setProcesses(filteredData)); | |||
| }); | |||
| it("should handle process to set it done in case of finish success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: { isSuccess: true } }; | |||
| api.doneProcess = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, finishProcess, { | |||
| payload: { | |||
| id: 1, | |||
| name: "Some random name", | |||
| applicantId: 5, | |||
| schedulerId: 10, | |||
| }, | |||
| }).done; | |||
| expect(api.doneProcess.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setDoneProcess(mockedCall.data)); | |||
| }); | |||
| it("should handle error in case of finish process exception", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.doneProcess = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, finishProcess, { | |||
| payload: { | |||
| id: 1, | |||
| name: "Some random name", | |||
| applicantId: 5, | |||
| schedulerId: 10, | |||
| }, | |||
| }).done; | |||
| expect(api.doneProcess.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setDoneProcessError(error.response.data.message) | |||
| ); | |||
| }); | |||
| it("should handle process status update", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: { isSuccess: true } }; | |||
| api.updateStatus = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeStatus, { | |||
| payload: { | |||
| data: { | |||
| schedulerId: 3, | |||
| appointment: "22-10-2023", | |||
| newStatus: "Odrađen", | |||
| processId: 1, | |||
| }, | |||
| }, | |||
| }).done; | |||
| expect(api.updateStatus.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setUpdateStatusSucc()); | |||
| }); | |||
| it("should call responsehandler while handling process status update", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: { isSuccess: true } }; | |||
| api.updateStatus = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeStatus, { | |||
| payload: { | |||
| data: { | |||
| schedulerId: 3, | |||
| appointment: "22-10-2023", | |||
| newStatus: "Odrađen", | |||
| processId: 1, | |||
| }, | |||
| responseHandler: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| }); | |||
| 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 = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeStatus, { | |||
| payload: { | |||
| data: { | |||
| schedulerId: 3, | |||
| appointment: "22-10-2023", | |||
| newStatus: "Odrađen", | |||
| processId: 1, | |||
| }, | |||
| }, | |||
| }).done; | |||
| expect(api.updateStatus.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setUpdateStatusErr(error.response.data.message) | |||
| ); | |||
| }); | |||
| it("should not call responseHandler if exception is thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.updateStatus = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeStatus, { | |||
| payload: { | |||
| data: { | |||
| schedulerId: 3, | |||
| appointment: "22-10-2023", | |||
| newStatus: "Odrađen", | |||
| processId: 1, | |||
| }, | |||
| responseHandler: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).not.toHaveBeenCalled(); | |||
| }); | |||
| it("should handle interviewer update", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: { isSuccess: true } }; | |||
| api.updateInterviewer = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeInterviewer, { | |||
| payload: { | |||
| data: { | |||
| schedulerId: 1, | |||
| processId: 2, | |||
| }, | |||
| // responseHandler: apiSuccess, | |||
| }, | |||
| }).done; | |||
| expect(api.updateInterviewer.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setUpdateInterviewerSucc()); | |||
| }); | |||
| it("should call response handler on change success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: { isSuccess: true } }; | |||
| api.updateInterviewer = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| const mockfn = jest.fn(); | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeInterviewer, { | |||
| payload: { | |||
| data: { | |||
| schedulerId: 1, | |||
| processId: 2, | |||
| }, | |||
| responseHandler: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(mockfn).toHaveBeenCalled(); | |||
| }); | |||
| it("should handle interviewer update error if exception is thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.updateInterviewer = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeInterviewer, { | |||
| payload: { | |||
| data: { | |||
| schedulerId: 1, | |||
| processId: 2, | |||
| }, | |||
| // responseHandler: mockfn, | |||
| }, | |||
| }).done; | |||
| expect(api.updateInterviewer.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setUpdateInterviewerErr(error.response.data.message) | |||
| ); | |||
| }); | |||
| it("should not call response handler if exception is thrown", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.updateInterviewer = jest.fn(() => Promise.reject(error)); | |||
| const mockfn = jest.fn(); | |||
| const fakeStore = { | |||
| getState: () => mockState.selections.processes, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, changeInterviewer, { | |||
| payload: { | |||
| data: { | |||
| schedulerId: 1, | |||
| 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) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,136 @@ | |||
| import * as redux from "react-redux"; | |||
| 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 { 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 { | |||
| 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 spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.user.user); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("should run register saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.register = jest.fn(() => Promise.resolve()); | |||
| const fakeStore = { | |||
| getState: () => ({ | |||
| isSuccess: false, | |||
| errorMessage: "", | |||
| }), | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, registerUser, { | |||
| payload: { | |||
| 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")); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,112 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import * as api from "../../request/scheduleRequest"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { SCHEDULE_FETCH } from "../../store/actions/schedule/scheduleActionConstants"; | |||
| import { getSchedule } from "../../store/saga/scheduleSaga"; | |||
| import { | |||
| fetchScheduleSuccess, | |||
| fetchScheduleError, | |||
| } from "../../store/actions/schedule/scheduleActions"; | |||
| import SchedulePage from "../../pages/SchedulePage/SchedulePage"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("SchedulePage render tests", () => { | |||
| const cont = ( | |||
| <ColorModeProvider> | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <SchedulePage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| </ColorModeProvider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.schedule.schedule); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get schedule request when rendered", () => { | |||
| render(cont); | |||
| const date = new Date() | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: SCHEDULE_FETCH, | |||
| payload: { | |||
| month: date.getMonth() + 1, | |||
| year: date.getFullYear(), | |||
| }, | |||
| }); | |||
| }); | |||
| it("should load and handle schedule in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.schedule.schedule }; | |||
| api.getSpecificSchedule = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.schedule.schedule, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getSchedule, { | |||
| payload: { | |||
| month: 12, | |||
| year: 2022, | |||
| }, | |||
| }).done; | |||
| expect(api.getSpecificSchedule.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(fetchScheduleSuccess(mockedCall.data)); | |||
| }); | |||
| it("should handle candidate load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn( | |||
| () => mockState.schedule.fetchScheduleErrorMessage | |||
| ); | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.schedule.fetchScheduleErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getSpecificSchedule = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.schedule.schedule, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getSchedule, { | |||
| payload: { | |||
| month: 12, | |||
| year: 2022, | |||
| }, | |||
| }).done; | |||
| expect(api.getSpecificSchedule.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| fetchScheduleError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,109 @@ | |||
| import { runSaga } from "redux-saga"; | |||
| import { | |||
| createScreeningTestError, | |||
| createScreeningTestSuccess, | |||
| fetchScreeningTestsError, | |||
| fetchScreeningTestsSuccess, | |||
| } from "../../store/actions/screeningTests/screeningTestActions"; | |||
| import { | |||
| createScreeningTest, | |||
| getScreeningTests, | |||
| } from "../../store/saga/screeningTestsSaga"; | |||
| import * as api from "../../request/screeningTestRequest"; | |||
| import * as redux from "react-redux"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("screening tests saga tests", () => { | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce("anything"); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should handle get tests saga with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: "Data" }; | |||
| api.getTests = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getScreeningTests).done; | |||
| expect(api.getTests.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| fetchScreeningTestsSuccess(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("Should handle get tests saga with errors", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| const mockedCall = { response: { data: { message: "Error" } } }; | |||
| api.getTests = jest.fn(() => Promise.reject(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getScreeningTests).done; | |||
| expect(api.getTests.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(fetchScreeningTestsError("Error")); | |||
| }); | |||
| it("Should handle create screening tests saga with actions", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: "Data" }; | |||
| api.createTest = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, createScreeningTest, { payload: {} }).done; | |||
| expect(api.createTest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| createScreeningTestSuccess(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("Should handle create screening tests saga with errors", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn(() => "Error"); | |||
| const mockedCall = { response: { data: { message: "Error" } } }; | |||
| api.createTest = jest.fn(() => Promise.reject(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, createScreeningTest, { payload: {} }).done; | |||
| expect(api.createTest.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(createScreeningTestError("Error")); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,97 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import StatsPage from "../../pages/StatsPage/StatsPage"; | |||
| import * as api from "../../request/statsRequests"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { | |||
| getStatsSuccess, | |||
| getStatsError, | |||
| } from "../../store/actions/stats/statsActions"; | |||
| import { FETCH_STATS_REQ } from "../../store/actions/stats/statsActionConstants"; | |||
| import { getAppStats } from "../../store/saga/statsSaga"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("Stats reducer tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <StatsPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get stats request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FETCH_STATS_REQ, | |||
| }); | |||
| }); | |||
| it("should load and handle stats in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState }; | |||
| api.getStats = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getAppStats).done; | |||
| expect(api.getStats.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(getStatsSuccess(mockedCall.data)); | |||
| }); | |||
| it("should handle stats load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn( | |||
| () => mockState.stats.fetchStatsErrorMessage | |||
| ); | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.stats.fetchStatsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getStats = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getAppStats).done; | |||
| expect(api.getStats.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| getStatsError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,127 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import { FILTER_CANDIDATES } from "../../store/actions/candidates/candidatesActionConstants"; | |||
| import TableViewPage from "../../pages/CandidatesPage/TableViewPage"; | |||
| import * as api from "../../request/candidatesRequest"; | |||
| import { runSaga } from "redux-saga"; | |||
| import * as fc from "../../store/saga/candidatesSaga"; | |||
| import { | |||
| filterCandidatesSuccess, | |||
| filterCandidatesError, | |||
| } from "../../store/actions/candidates/candidatesActions"; | |||
| import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("TableViewPage render tests", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/candidates", | |||
| }, | |||
| }, | |||
| setPage: jest.fn(), | |||
| sliderValue: [0, 2], | |||
| startingDate: "", | |||
| endingDate: "", | |||
| typesOfEmployments: [], | |||
| technologie: [], | |||
| page: 1, | |||
| search: "", | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <TableViewPage {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector | |||
| .mockReturnValueOnce(mockState.candidates.candidates) | |||
| .mockReturnValueOnce(mockState.candidates.pagination); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch filter candidates request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FILTER_CANDIDATES, | |||
| payload: { | |||
| currentPage: 1, | |||
| employmentType: "", | |||
| maxDateOfApplication: "", | |||
| maxExperience: 0, | |||
| minDateOfApplication: "", | |||
| minExperience: 0, | |||
| pageSize: PAGE_SIZE_CANDIDATES, | |||
| technologies: [], | |||
| }, | |||
| }); | |||
| }); | |||
| it("should load and handle candidates in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.candidates.items }; | |||
| api.getFilteredCandidates = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.candidates.items, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.filterCandidates, {}).done; | |||
| expect(api.getFilteredCandidates.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| filterCandidatesSuccess(mockedCall.data) | |||
| ); | |||
| }); | |||
| it("should handle technologies load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn( | |||
| () => mockState.candidates.fetchCandidatesErrorMessage | |||
| ); | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.candidates.fetchCandidatesErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getFilteredCandidates = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.candidates.candidates, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, fc.filterCandidates, {}).done; | |||
| expect(api.getFilteredCandidates.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| filterCandidatesError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,108 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import * as api from '../../request/usersRequest' | |||
| import UserDetails from "../../pages/UsersPage/UserDetails"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import { | |||
| USER_DETAILS_REQ, | |||
| } from "../../store/actions/users/usersActionConstants"; | |||
| import { userDetails } from "../../store/saga/usersSaga"; | |||
| 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"), | |||
| useParams: () => ({ | |||
| id: 1, | |||
| }), | |||
| })); | |||
| describe("UserDetails reducer tests", () => { | |||
| const cont = ( | |||
| <ColorModeProvider> | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <UserDetails /> | |||
| </Router> | |||
| </redux.Provider> | |||
| </ColorModeProvider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.user.user); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get user details with params request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: USER_DETAILS_REQ, | |||
| payload: { id: 1 }, | |||
| }); | |||
| }); | |||
| it("should run userDetails saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.userDetailsRequest = jest.fn(() => Promise.resolve({ data: mockState.user.user })); | |||
| const fakeStore = { | |||
| getState: () => mockState.user, | |||
| 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")); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,211 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import UsersPage from "../../pages/UsersPage/UsersPage"; | |||
| import * as api from "../../request/usersRequest"; | |||
| 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 * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| describe("User management reducer tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <UsersPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.users); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get users request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FETCH_USERS_REQ, | |||
| }); | |||
| }); | |||
| it("should handle users load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.selections.fetchSelectionsErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getAllUsers = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getUsers).done; | |||
| expect(api.getAllUsers.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setUsersError(undefined)); | |||
| }); | |||
| it("should run getUsers saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.getAllUsers = jest | |||
| .fn() | |||
| .mockResolvedValue({ data: mockState.users.users }); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| // wait for saga to complete | |||
| await runSaga(fakeStore, getUsers).done; | |||
| expect(api.getAllUsers.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setUsers(mockState.users.users)); | |||
| }); | |||
| it("should run enableUser saga function with actions", async () => { | |||
| const dispatchedActions = []; | |||
| api.enableUserRequest = jest.fn(() => Promise.resolve(1)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| 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 = []; | |||
| api.deleteUserRequest = jest.fn(() => Promise.resolve({ data: 1 })); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, deleteUser, { | |||
| payload: { | |||
| id: 1, | |||
| }, | |||
| }).done; | |||
| 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,96 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import * as api from "../../request/usersRequest"; | |||
| import { runSaga } from "redux-saga"; | |||
| import { | |||
| setUsers, | |||
| setUsersError, | |||
| } from "../../store/actions/users/usersActions"; | |||
| import { FETCH_USERS_REQ } from "../../store/actions/users/usersActionConstants"; | |||
| import { getUsers } from "../../store/saga/usersSaga"; | |||
| import * as helper from "../../util/helpers/rejectErrorCodeHelper"; | |||
| import UsersPage from "../../pages/UsersPage/UsersPage"; | |||
| describe("UsersPage reducer tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <UsersPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.users); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should dispatch get users request when rendered", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toHaveBeenCalledWith({ | |||
| type: FETCH_USERS_REQ, | |||
| }); | |||
| }); | |||
| it("should load and handle users in case of success", async () => { | |||
| const dispatchedActions = []; | |||
| const mockedCall = { data: mockState.users }; | |||
| api.getAllUsers = jest.fn(() => Promise.resolve(mockedCall)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getUsers).done; | |||
| expect(api.getAllUsers.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual(setUsers(mockedCall.data)); | |||
| }); | |||
| it("should handle users load errors in case of failure", async () => { | |||
| const dispatchedActions = []; | |||
| helper.rejectErrorCodeHelper = jest.fn( | |||
| () => mockState.users.fetchUsersErrorMessage | |||
| ); | |||
| const error = { | |||
| response: { | |||
| data: { message: mockState.users.fetchUsersErrorMessage }, | |||
| }, | |||
| }; | |||
| api.getAllUsers = jest.fn(() => Promise.reject(error)); | |||
| const fakeStore = { | |||
| getState: () => mockState.users, | |||
| dispatch: (action) => dispatchedActions.push(action), | |||
| }; | |||
| await runSaga(fakeStore, getUsers).done; | |||
| expect(api.getAllUsers.mock.calls.length).toBe(1); | |||
| expect(dispatchedActions).toContainEqual( | |||
| setUsersError(error.response.data.message) | |||
| ); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,80 @@ | |||
| import { Router } from "react-router-dom"; | |||
| import { SelectionProvider } from "../../context/SelectionContext"; | |||
| import * as redux from "react-redux"; | |||
| import { fireEvent, render, screen } from "@testing-library/react"; | |||
| import store from "../../store"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import SelectionCard from "../../components/Selection/SelectionCard"; | |||
| import userEvent from "@testing-library/user-event"; | |||
| describe("SelectionProcessPage render tests *first in order", () => { | |||
| var props = { | |||
| item: mockState.selections.processes[1].selectionProcesses[0], | |||
| click: jest.fn(), | |||
| dragStart: jest.fn(), | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <SelectionProvider> | |||
| <Router history={history}> | |||
| <SelectionCard {...props} /> | |||
| </Router> | |||
| </SelectionProvider> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| // Mock useDisptach hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render card", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("sel-card")).toBeDefined(); | |||
| }); | |||
| it("Should render schedule", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("process-date")).toBeDefined(); | |||
| }); | |||
| // to be completed | |||
| // it("Should dispatch status change action when option 'done' is selected", async () => { | |||
| // render(cont); | |||
| // fireEvent.click(screen.getByTestId("status-btn")); | |||
| // var select = screen.getByTestId("status-select-drop"); | |||
| // fireEvent.change(select, { target: { value: "Odrađen" } }); | |||
| // // userEvent.click(screen.getByRole(screen.getByTestId("status-select-drop"), "button")); | |||
| // // await waitFor(() => userEvent.click(screen.getByText(/odrađen/i))); | |||
| // // expect(screen.getByRole("heading")).toHaveTextContent(/odrađen/i); | |||
| // expect(mockDispatch).toHaveBeenCalledWith( | |||
| // setDoneProcessReq({ | |||
| // id: props.item.id, | |||
| // name: "Some random name", | |||
| // applicantId: props.item.applicant.applicantId, | |||
| // }) | |||
| // ); | |||
| // }); | |||
| }); | |||
| @@ -0,0 +1,143 @@ | |||
| import { Router } from "react-router-dom"; | |||
| import { SelectionProvider } from "../../context/SelectionContext"; | |||
| import * as redux from "react-redux"; | |||
| import Selection from "../../components/Selection/Selection"; | |||
| import { fireEvent, render, screen } from "@testing-library/react"; | |||
| import store from "../../store"; | |||
| import history from "../../store/utils/history"; | |||
| describe("SelectionProcessPage render tests *first in order", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/selectionFlow", | |||
| }, | |||
| }, | |||
| order: 0, | |||
| modalEvent: jest.fn(), | |||
| selection: { | |||
| id: 1, | |||
| name: "HR intervju", | |||
| selectionProcesses: [], | |||
| // PropTypes.arrayOf( | |||
| // PropTypes.shape({ | |||
| // id: PropTypes.number, | |||
| // name: PropTypes.string, | |||
| // date: PropTypes.string, | |||
| // status: PropTypes.string, | |||
| // currentSelection: PropTypes.number, | |||
| // map: PropTypes.func, | |||
| // applicant: PropTypes.shape({ | |||
| // firstName: PropTypes.string, | |||
| // lastName: PropTypes.string, | |||
| // }), | |||
| // }) | |||
| // ), | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <SelectionProvider> | |||
| <Router history={history}> | |||
| <Selection {...props} /> | |||
| </Router> | |||
| </SelectionProvider> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render add button if selection is first in order", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("interview-image")).toBeDefined(); | |||
| }); | |||
| it("Should render empty selection message if no proccesses exist", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("empty-selection")).toBeDefined(); | |||
| }); | |||
| it("Should call modal event if add button has been clicked", () => { | |||
| render(cont); | |||
| fireEvent.click(screen.getByTestId("interview-image")); | |||
| expect(props.modalEvent).toHaveBeenCalled(); | |||
| }); | |||
| }); | |||
| describe("SelectionProcessPage render tests *first in order", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/selectionFlow", | |||
| }, | |||
| }, | |||
| order: 1, | |||
| modalEvent: jest.fn(), | |||
| selection: { | |||
| id: 1, | |||
| name: "HR intervju", | |||
| selectionProcesses: [ | |||
| { | |||
| id: 1, | |||
| name: "random", | |||
| date: "02-05-2022", | |||
| status: "Zakazan", | |||
| currentSelection: 1, | |||
| applicant: { | |||
| firstName: "Meris", | |||
| lastName: "Ahmatovic", | |||
| }, | |||
| }, | |||
| ], | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <SelectionProvider> | |||
| <Router history={history}> | |||
| <Selection {...props} /> | |||
| </Router> | |||
| </SelectionProvider> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should not render add button if not first in order", () => { | |||
| render(cont); | |||
| expect(screen.queryByTestId("interview-image")).toBe(null); | |||
| }); | |||
| it("Should render empty selection message if no proccesses exist", () => { | |||
| render(cont); | |||
| expect(screen.queryByTestId("empty-selection")).toBe(null); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,62 @@ | |||
| import { render, screen, waitFor, fireEvent } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import AdDetailsCandidateCard from "../../components/Ads/AdDetailsCandidateCard"; | |||
| describe("Ad details candidate card ui tests", () => { | |||
| const props = { | |||
| className: "ad-details-card", | |||
| id: 1, | |||
| firstName: "Ermin", | |||
| lastName: "Bronja", | |||
| experience: 1, | |||
| cv: "http://", | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/ads/1", | |||
| }, | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <AdDetailsCandidateCard {...props} /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue(mockState.ads.ads); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should load ad details candidate card component", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("ad-details-candidate")).toBeDefined(); | |||
| }); | |||
| it("Should navigate on candidates page when button clicked", async () => { | |||
| render(cont); | |||
| waitFor(() => { | |||
| fireEvent.click(screen.getByTestId("ad-details-candidate-title-link")); | |||
| expect(props.history.push).toHaveBeenCalledWith("/candidates/1"); | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,104 @@ | |||
| import { render, screen, fireEvent, waitFor } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import AdDetailsPage from "../../pages/AdsPage/AdDetailsPage"; | |||
| import store from "../../store"; | |||
| import { mockState } from "../../mockState"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| describe("AdDetailsPage render tests", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/ads/1", | |||
| }, | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <AdDetailsPage {...props} /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue(mockState.ads.ads[0]); | |||
| }); | |||
| afterEach(() => { | |||
| jest.resetAllMocks(); | |||
| }); | |||
| it("Should render AdDetailsPage", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("ad-details-page")).toBeDefined(); | |||
| }); | |||
| it("Should render modal when click archive ad button", () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click(container.getElementsByClassName("archive-ad-button")[0]); | |||
| expect(screen.getByTestId("alert-container")).toBeDefined(); | |||
| }); | |||
| it("Should render ads page when confirm archive ad modal", async () => { | |||
| const { container } = render(cont); | |||
| waitFor(() => { | |||
| fireEvent.click(container.getElementsByClassName("archive-ad-button")[0]); | |||
| fireEvent.click(container.getElementsByClassName("dialog-btn")[1]); | |||
| waitFor(() => expect(props.history.push).toHaveBeenCalledWith('/ads')); | |||
| }); | |||
| }); | |||
| it("Should render apply for ad button", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("apply-for-ad-button")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render apply for ad modal after click button", () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click(container.getElementsByClassName("apply-for-ad-button")[0]); | |||
| const a = screen.getByTestId("custom-modal-test-id"); | |||
| expect(screen.getByTestId("custom-modal-test-id")).toBeDefined(); | |||
| }); | |||
| it("Should render go back button", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("ad-details-buttons-link")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should go back when click button", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click( | |||
| container.getElementsByClassName("ad-details-buttons-link")[0] | |||
| ); | |||
| const arg = { pathname: "/ads" }; | |||
| waitFor(() => expect(props.history.push).toHaveBeenCalledWith(arg)); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,101 @@ | |||
| import { render, fireEvent, waitFor } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { mockState } from "../../mockState"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import AdsCandidatesPage from "../../pages/CandidatesPage/AdsCandidatesPage"; | |||
| describe("TableViewPage render tests", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/candidates", | |||
| }, | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <AdsCandidatesPage search="" {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.candidates.adsCandidates); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("ads-candidates-container")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Number of sliders should be equal to length of our adsCandidates array", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("ads-candidates").length).toBe( | |||
| mockState.candidates.adsCandidates.length | |||
| ); | |||
| }); | |||
| it("Number of candidates in slider (vissible and hidden) should be equal to the number of candidates which applied for ad", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container | |||
| .getElementsByClassName("ads-candidates")[0] | |||
| .getElementsByClassName("slick-slide").length | |||
| ).toBe(mockState.candidates.adsCandidates[0].applicants.length); | |||
| }); | |||
| it("Number of arrows (left and right) should be 1 because there is more than 4 candidates which applied for ad", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("active-ads-ads-arrows").length | |||
| ).toBe(1); | |||
| }); | |||
| it("After clicking on right arrow of first slider, first slider should show fifth candidate as forth card of slider", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click( | |||
| container | |||
| .getElementsByClassName("active-ads-ads-arrows")[0] | |||
| .getElementsByTagName("button")[1] | |||
| ); | |||
| await waitFor(() => | |||
| expect( | |||
| container | |||
| .getElementsByClassName("ads-candidates")[0] | |||
| .getElementsByClassName("slick-active")[0] | |||
| .getElementsByClassName("candidate-card-container")[0] | |||
| .getElementsByClassName("candidate-card-applicant-name")[0] | |||
| .textContent | |||
| ).toBe( | |||
| mockState.candidates.adsCandidates[0].applicants[3].firstName + | |||
| " " + | |||
| mockState.candidates.adsCandidates[0].applicants[3].lastName | |||
| ) | |||
| ); | |||
| }); | |||
| it("Should render candidate details page after clicking on candidate card", () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click( | |||
| container.getElementsByClassName("candidate-card-container")[0] | |||
| ); | |||
| const arg = { pathname: "/candidates/1" }; | |||
| expect(props.history.push).toHaveBeenCalledWith(arg); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,154 @@ | |||
| import { render, screen, fireEvent, waitFor } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import AdsPage from "../../pages/AdsPage/AdsPage"; | |||
| import store from "../../store"; | |||
| import { mockState } from "../../mockState"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| describe("AdsPage render tests", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/ads", | |||
| }, | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <AdsPage {...props} /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector | |||
| .mockReturnValueOnce(mockState.ads.ads) | |||
| .mockReturnValueOnce([ | |||
| { | |||
| name: ".NET", | |||
| technologyId: 1, | |||
| technologyType: "Backend", | |||
| isChecked: false, | |||
| }, | |||
| ]) | |||
| }); | |||
| afterEach(() => { | |||
| jest.resetAllMocks(); | |||
| }); | |||
| it("Should render ads", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("ads-page")).toBeDefined(); | |||
| }); | |||
| it("Should be rendered button which is used for showing input responsible for searching by name", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("ads-page-btn")[0]).toBeDefined(); | |||
| }); | |||
| it("Should be rendered button for toggling filters modal", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("ads-page-btn")[1]).toBeDefined(); | |||
| }); | |||
| it("Should be rendered button for adding new ad", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("ads-page-btn")[2]).toBeDefined(); | |||
| }); | |||
| it("Should render CreateAdPage when click Add Ad button", () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click(container.getElementsByClassName("ads-page-btn")[2]); | |||
| expect(props.history.push).toHaveBeenCalledWith("/create-ad"); | |||
| }); | |||
| it("Input for searching by title should not be shown when component is initialy rendered", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("ads-page-search-by-title")[0].style | |||
| .visibility | |||
| ).toBe("hidden"); | |||
| }); | |||
| it("Should be rendered ad cards", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("ad-card").length).toBeGreaterThan( | |||
| 0 | |||
| ); | |||
| }); | |||
| it("Should be rendered archive ad cards", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("archive-ad").length).toBe(0); | |||
| }); | |||
| it("Should render filter drawer after click filter button", () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click(container.getElementsByClassName("fltr-btn")[0]); | |||
| expect(screen.getByTestId("ad-filters-drawer")).toBeDefined(); | |||
| }); | |||
| it("Should render arrow buttons for active ads slider", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("active-ads-ads-arrows") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render arrow buttons for archived ads slider", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("archived-ads-ads-arrows") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should filter ads when click search button", async () => { | |||
| const { container } = render(cont); | |||
| waitFor(() => { | |||
| fireEvent.click(container.getElementsByClassName("fltr-btn")[0]); | |||
| fireEvent.click( | |||
| container.getElementsByClassName("ad-filters-checkbox")[0] | |||
| ); | |||
| fireEvent.click(container.getByTestId("ad-filters-submit")[0]); | |||
| expect( | |||
| container.getElementsByClassName("ad-card").length | |||
| ).toBeGreaterThan(0); | |||
| }); | |||
| }); | |||
| it("Should render Ads", async () => { | |||
| const { container } = render(cont); | |||
| waitFor(() => | |||
| expect( | |||
| container.getElementsByClassName("ad-card").length | |||
| ).toBeGreaterThan(0) | |||
| ); | |||
| }); | |||
| it("Should navigate to ad details when click on ad card", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click(container.getElementsByClassName("ad-card")[0]); | |||
| expect(props.history.push).toHaveBeenCalledWith("/ads/1"); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,53 @@ | |||
| import { render, screen } from "@testing-library/react"; | |||
| import { Provider } from "react-redux"; | |||
| import { Router } from "react-router-dom"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import SelectionProcessOfApplicantPage from "../../pages/SelectionProcessPage/SelectionProcessOfApplicantPage"; | |||
| import store from "../../store"; | |||
| import history from "../../store/utils/history"; | |||
| import * as redux from "react-redux"; | |||
| import { mockState } from "../../mockState"; | |||
| describe("applicant selection process details test", () => { | |||
| var cont = ( | |||
| <Router history={history}> | |||
| <Provider store={store}> | |||
| <ColorModeProvider> | |||
| <SelectionProcessOfApplicantPage /> | |||
| </ColorModeProvider> | |||
| </Provider> | |||
| </Router> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| // Mock useSelector hook | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue(mockState.applSelection); | |||
| // Mock useDispatch hook | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| // Mock dispatch function returned from useDispatch | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValueOnce(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("should render", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("appl-sel")).toBeDefined(); | |||
| }); | |||
| // ? | |||
| // it("should render applicant selection", () => { | |||
| // render(cont); | |||
| // expect(screen.getByTestId("appSelection")).toBeDefined(); | |||
| // }); | |||
| }); | |||
| @@ -0,0 +1,110 @@ | |||
| import { render, screen, waitFor, fireEvent } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import ApplyForAdFirstStage from "../../components/Ads/ApplyForAdFirstStage"; | |||
| describe("Apply for ad first stage ui tests", () => { | |||
| const props = { | |||
| firstName: "E", | |||
| setFirstName: jest.fn(), | |||
| lastName: "B", | |||
| gender: "Male", | |||
| setGender: jest.fn(), | |||
| setLastName: jest.fn(), | |||
| dateOfBirth: new Date(), | |||
| setDateOfBirth: jest.fn(), | |||
| phoneNumber: "0", | |||
| setPhoneNumber: jest.fn(), | |||
| onIncreaseStage: jest.fn(), | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <ApplyForAdFirstStage {...props} /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue(mockState.ads.ads); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render firstName input", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("apply-for-ad-modal-first-name-input")).toBeDefined(); | |||
| }); | |||
| it("Should change firstName on changing input", async () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId("apply-for-ad-modal-first-name-input"), | |||
| { target: { value: "Ermin" } } | |||
| ); | |||
| waitFor(() => expect(props.setFirstName).toHaveBeenCalled()); | |||
| }); | |||
| it("Should change last on changing input", async () => { | |||
| render(cont); | |||
| fireEvent.change(screen.getByTestId("apply-for-ad-modal-last-name-input"), { | |||
| target: { value: "Bronja" }, | |||
| }); | |||
| waitFor(() => expect(props.setLastName).toHaveBeenCalled()); | |||
| }); | |||
| it("Should select male gender", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click( | |||
| container.getElementsByClassName("apply-for-ad-modal-gender-input")[0] | |||
| ); | |||
| waitFor(() => expect(props.setGender).toHaveBeenCalled()); | |||
| }); | |||
| it("Should select female gender", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click( | |||
| container.getElementsByClassName("apply-for-ad-modal-gender-input")[1] | |||
| ); | |||
| waitFor(() => expect(props.setGender).toHaveBeenCalled()); | |||
| }); | |||
| it("Should change date of birth", async () => { | |||
| render(cont); | |||
| fireEvent.change(screen.getByTestId("apply-for-ad-modal-date-of-birth"), { | |||
| target: { value: "1998-05-05" }, | |||
| }); | |||
| waitFor(() => expect(props.setDateOfBirth).toHaveBeenCalled()); | |||
| }); | |||
| it("Should change phone number", async () => { | |||
| render(cont); | |||
| fireEvent.change(screen.getByTestId("apply-for-ad-modal-phone-number"), { target: { value: "0000000000" } }); | |||
| waitFor(() => expect(props.setPhoneNumber).toHaveBeenCalled()); | |||
| }); | |||
| it("Should click go forward button", async () => { | |||
| render(cont); | |||
| fireEvent.click(screen.getByTestId("apply-for-ad-modal-go-forward-button")); | |||
| waitFor(() => expect(props.onIncreaseStage).toHaveBeenCalled()); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,106 @@ | |||
| import { render, screen, waitFor, fireEvent } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import ApplyForAdFourthStage from "../../components/Ads/ApplyForAdFourthStage"; | |||
| describe("Apply for ad fourth stage ui tests", () => { | |||
| const props = { | |||
| coverLetter: "", | |||
| setCoverLetter: jest.fn(), | |||
| pdfFile: null, | |||
| setPdfFile: jest.fn(), | |||
| onDecreaseStage: jest.fn(), | |||
| onFinishedFourStages: jest.fn(), | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <ApplyForAdFourthStage {...props} /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let file; | |||
| beforeEach(() => { | |||
| file = new File(["(⌐□_□)"], "test.png", { type: "image/png" }); | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue(mockState.ads.ads); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render apply for ad fourth stage modal", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("apply-for-ad-modal-fourth-stage")).toBeDefined(); | |||
| }); | |||
| it("Should change pdfFile", async () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId("apply-for-ad-modal-fourth-stage-pdf-input"), | |||
| { target: { files: [file] } } | |||
| ); | |||
| waitFor(() => expect(props.setPdfFile).toHaveBeenCalled()); | |||
| }); | |||
| it("Should change coverLetter", async () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId("apply-for-ad-modal-fourth-stage-cover-letter-input"), | |||
| { target: { value: "Cover Letter" } } | |||
| ); | |||
| waitFor(() => expect(props.setPdfFile).toHaveBeenCalled()); | |||
| }); | |||
| it("Should go back on click button", async () => { | |||
| render(cont); | |||
| fireEvent.click( | |||
| screen.getByTestId("apply-for-ad-modal-fourth-stage-go-back-button") | |||
| ); | |||
| waitFor(() => expect(props.onDecreaseStage).toHaveBeenCalled()); | |||
| }); | |||
| it("Should finish stages on click button", async () => { | |||
| render(cont); | |||
| fireEvent.click( | |||
| screen.getByTestId("apply-for-ad-modal-fourth-stage-go-forward-button") | |||
| ); | |||
| waitFor(() => expect(props.onFinishedFourStages).toHaveBeenCalled()); | |||
| }); | |||
| it("Drag and drop", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.drop(container.getElementsByClassName("uploadCV-input")[0], { | |||
| dataTransfer: { files: [file] }, | |||
| }); | |||
| }); | |||
| it("Drag and drop over", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.dragOver(container.getElementsByClassName("uploadCV-input")[0], { | |||
| dataTransfer: { files: [file] }, | |||
| }); | |||
| }); | |||
| it("Drag and drop leave", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.dragOver(container.getElementsByClassName("uploadCV-input")[0], { | |||
| dataTransfer: { files: [file] }, | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,125 @@ | |||
| import { render, screen, waitFor, fireEvent } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import ApplyForAdSecondStage from "../../components/Ads/ApplyForAdSecondStage"; | |||
| describe("Apply for ad second stage ui tests", () => { | |||
| const props = { | |||
| professionalQualification: "Professional Qualification", | |||
| setProfessionalQualification: jest.fn(), | |||
| technologies: [ | |||
| { | |||
| value: ".NET", | |||
| isChecked: false, | |||
| technologyId: 1, | |||
| technologyType: "Backend", | |||
| }, | |||
| { | |||
| value: "React", | |||
| isChecked: false, | |||
| technologyId: 2, | |||
| technologyType: "Frontend", | |||
| }, | |||
| { | |||
| value: "Git", | |||
| isChecked: false, | |||
| technologyId: 3, | |||
| technologyType: "Other", | |||
| }, | |||
| ], | |||
| setTechnologies: jest.fn(), | |||
| experience: 1, | |||
| setExperience: jest.fn(), | |||
| onIncreaseStage: jest.fn(), | |||
| onDecreaseStage: jest.fn(), | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <ApplyForAdSecondStage {...props} /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue(mockState.ads.ads); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render apply for ad second stage", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("apply-for-ad-second-stage")).toBeDefined(); | |||
| }); | |||
| it("Should change professional qualification input", () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId( | |||
| "apply-for-ad-second-stage-professional-qualification" | |||
| ), | |||
| { | |||
| target: { value: "Faculty" }, | |||
| } | |||
| ); | |||
| expect(props.setProfessionalQualification).toHaveBeenCalled(); | |||
| }); | |||
| it("Should render backend technology", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("apply-for-ad-second-stage-checkbox")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render frontend technology", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("apply-for-ad-second-stage-checkbox")[1] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render others technology", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("apply-for-ad-second-stage-checkbox")[2] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should change experience", async () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId("apply-for-ad-second-stage-experience-input"), | |||
| { target: { value: 2 } } | |||
| ); | |||
| waitFor(() => expect(props.professionalQualification).toHaveBeenCalled()); | |||
| }); | |||
| it("Should change backend technology to checked", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click( | |||
| container.getElementsByClassName("apply-for-ad-second-stage-checkbox")[0] | |||
| ); | |||
| waitFor(() => expect(props.technologies[0]).toBe(true)); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,110 @@ | |||
| import { render, screen, waitFor, fireEvent } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import ApplyForAdThirdStage from "../../components/Ads/ApplyForAdThirdStage"; | |||
| describe("Apply for ad third stage ui tests", () => { | |||
| const props = { | |||
| onIncreaseStage: jest.fn(), | |||
| onDecreaseStage: jest.fn(), | |||
| linkedinLink: "", | |||
| setLinkedinLink: jest.fn(), | |||
| githubLink: "", | |||
| setGithubLink: jest.fn(), | |||
| bitBucketLink: "", | |||
| setBitBucketLink: jest.fn(), | |||
| email: "", | |||
| setEmail: jest.fn(), | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <ApplyForAdThirdStage {...props} /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue(mockState.ads.ads); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should change linkedin input", async () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId("apply-for-ad-modal-third-stage-linkedin-input"), | |||
| { target: { value: "https://linkedin" } } | |||
| ); | |||
| waitFor(() => expect(props.linkedinLink).toBe("https://linkedin")); | |||
| }); | |||
| it("Should render linkedin input", () => { | |||
| render(cont); | |||
| expect( | |||
| screen.getByTestId("apply-for-ad-modal-third-stage-linkedin-input") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should change github input", async () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId("apply-for-ad-modal-third-stage-github-input"), | |||
| { target: { value: "https://github" } } | |||
| ); | |||
| waitFor(() => expect(props.githubLink).toBe("https://github")); | |||
| }); | |||
| it("Should change bitbucket input", async () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId("apply-for-ad-modal-third-stage-bitbucket-input"), | |||
| { target: { value: "https://bitbucket" } } | |||
| ); | |||
| waitFor(() => expect(props.bitBucketLink).toBe("https://bitbucket")); | |||
| }); | |||
| it("Should change email input", async () => { | |||
| render(cont); | |||
| fireEvent.change( | |||
| screen.getByTestId("apply-for-ad-modal-third-stage-email-input"), | |||
| { target: { value: "ermin.bronja@dilig.net" } } | |||
| ); | |||
| waitFor(() => expect(props.email).toBe("ermin.bronja@dilig.net")); | |||
| }); | |||
| it("Should go back when button clicked", async () => { | |||
| render(cont); | |||
| fireEvent.click( | |||
| screen.getByTestId("apply-for-ad-modal-third-stage-go-back-button") | |||
| ); | |||
| waitFor(() => expect(props.onDecreaseStage).toHaveBeenCalled()); | |||
| }); | |||
| it("Should go forward when button clicked", async () => { | |||
| render(cont); | |||
| fireEvent.click( | |||
| screen.getByTestId("apply-for-ad-modal-third-stage-go-forward-button") | |||
| ); | |||
| waitFor(() => expect(props.onIncreaseStage).toHaveBeenCalled()); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,199 @@ | |||
| import { render, fireEvent, screen, waitFor } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { mockState } from "../../mockState"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import CandidateDetailsPage from "../../pages/CandidatesPage/CandidateDetailsPage"; | |||
| import mediaQuery from "css-mediaquery"; | |||
| function createMatchMedia(width) { | |||
| return (query) => ({ | |||
| matches: mediaQuery.match(query, { width }), | |||
| addListener: () => {}, | |||
| removeListener: () => {}, | |||
| }); | |||
| } | |||
| describe("CandidateDetailsPage render tests", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/candidates/1", | |||
| }, | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <CandidateDetailsPage {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| window.matchMedia = createMatchMedia(362); | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector | |||
| .mockReturnValueOnce(mockState.users.users) | |||
| .mockReturnValueOnce(mockState.users.user) | |||
| .mockReturnValueOnce(mockState.candidate.candidate) | |||
| .mockReturnValueOnce(mockState.users.users) | |||
| .mockReturnValueOnce(mockState.users.user) | |||
| .mockReturnValueOnce(mockState.candidate.candidate) | |||
| .mockReturnValueOnce(mockState.users.users) | |||
| .mockReturnValueOnce(mockState.users.user) | |||
| .mockReturnValueOnce(mockState.candidate.candidate); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("main-candidate-container")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Initialy should dispatch two methods", () => { | |||
| render(cont); | |||
| expect(mockDispatch).toBeCalledTimes(2); | |||
| }); | |||
| it("Should render candidate name", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("candidate-lower-header")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render button for deleting candidate", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("candidate-btn")[0]).toBeDefined(); | |||
| }); | |||
| it("Should represent one year of experience for the candidate", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("candidate-experience").textContent).toBe( | |||
| "candidates.experience:1" | |||
| ); | |||
| }); | |||
| it("Should represent all technologies of candidate", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("technology-candidate-card").length | |||
| ).toBe(2); | |||
| }); | |||
| it("It should show Muski inside paragraph for gender because value of gender property of our candidate is M", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("candidate-gender").textContent).toBe("common.male"); | |||
| }); | |||
| it("Should render dialog after clicking button for deleting candidate", () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click(container.getElementsByClassName("candidate-btn")[0]); | |||
| expect(screen.getByTestId("alert-container")).toBeDefined(); | |||
| }); | |||
| it("Should render input for sending comment", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("comment-input")[0]).toBeDefined(); | |||
| }); | |||
| it("Initially mention should not be rendered", async () => { | |||
| const { container } = render(cont); | |||
| await waitFor(() => | |||
| expect( | |||
| container.getElementsByClassName("comment-input_suggestions")[0] | |||
| ).toBeUndefined() | |||
| ); | |||
| }); | |||
| it("Should render mention list after entering @ inside our mention input", async () => { | |||
| const { container } = render(cont); | |||
| const input = container | |||
| .getElementsByClassName("comment-input")[0] | |||
| .querySelector("textarea"); | |||
| waitFor(() => { | |||
| fireEvent.change(input, { target: { value: "@" } }); | |||
| expect( | |||
| container | |||
| .getElementsByClassName("comment-input")[0] | |||
| .getElementsByClassName("comment-input_suggestions")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| }); | |||
| it("Should render first button for sending commment because width of screen is greater than 361", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("comment-send-btn")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Clicking button for sending comment should dispatch function", async () => { | |||
| const { container } = render(cont); | |||
| const input = container | |||
| .getElementsByClassName("comment-input")[0] | |||
| .querySelector("textarea"); | |||
| fireEvent.change(input, { target: { value: "some value" } }); | |||
| fireEvent.click(container.getElementsByClassName("comment-send-btn")[0]); | |||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(3)); | |||
| }); | |||
| it("Should not render second button for sending commment because width of screen is greater than 361", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("comment-send-btn-responsive")[0] | |||
| ).toBeUndefined(); | |||
| }); | |||
| it("Should render button for downloading CV", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("applicant-cv-button")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("should not render responsive right and left arrow because screen width is greater than 361", () => { | |||
| render(cont); | |||
| expect(screen.queryByTestId("candidate-ad-responsive-arrows")).toBeNull(); | |||
| }); | |||
| it("Should render two ads for candidate", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("applicant-add").length).toBe(2); | |||
| }); | |||
| it("Should render three comments", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("comment-sub-container").length | |||
| ).toBe(3); | |||
| }); | |||
| it("Should render page with all candidates", () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click( | |||
| container.getElementsByClassName("applicant-ads-back-button")[0] | |||
| ); | |||
| const arg = { pathname: "/candidates" }; | |||
| expect(props.history.push).toHaveBeenCalledWith(arg); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,72 @@ | |||
| import { fireEvent, render, screen, waitFor } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import { mockState } from "../../mockState"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import CandidateFilters from "../../components/Candidates/CandidateFilters"; | |||
| describe("Add ad modals ui tests", () => { | |||
| const props = { | |||
| open: true, | |||
| handleClose: jest.fn(), | |||
| pageSize: 3, | |||
| currentPage: 1, | |||
| isTableView: false, | |||
| technologies: [ | |||
| { | |||
| technologyId: 1, | |||
| name: ".NET", | |||
| technologyType: "Backend", | |||
| isChecked: true, | |||
| }, | |||
| ], | |||
| startingDate: "", | |||
| endingDate: "", | |||
| typesOfEmployments: [], | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <CandidateFilters {...props} /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should check checkbox", async () => { | |||
| const { container } = render(cont); | |||
| const a = container.getElementsByClassName( | |||
| "ad-filters-technologies-checkboxes-checkbox" | |||
| )[0]; | |||
| waitFor(() => { | |||
| fireEvent.click(a); | |||
| expect(a).toBeDefined(); | |||
| }); | |||
| }); | |||
| it("Should click type of employment button", async () => { | |||
| const { container } = render(cont); | |||
| const btn = container.getElementsByClassName("type-of-employment-btn"); | |||
| waitFor(() => { | |||
| fireEvent.click(btn[1]); | |||
| expect(btn).toBeDefined(); | |||
| }); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,120 @@ | |||
| import { render, screen, fireEvent, waitFor } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import CandidatesPage from "../../pages/CandidatesPage/CandidatesPage"; | |||
| import store from "../../store"; | |||
| import { mockState } from "../../mockState"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import mediaQuery from "css-mediaquery"; | |||
| function createMatchMedia(width) { | |||
| return (query) => ({ | |||
| matches: mediaQuery.match(query, { width }), | |||
| addListener: () => {}, | |||
| removeListener: () => {}, | |||
| }); | |||
| } | |||
| describe("CandidatesPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <CandidatesPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| window.matchMedia = createMatchMedia(601); | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValueOnce(mockState.technologies.technologies); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render first header because width of screen is greater than 600", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("candidates-header1")).toBeDefined(); | |||
| }); | |||
| it("Should render second header because width of screen is greater than 600", () => { | |||
| render(cont); | |||
| expect(screen.queryByTestId("candidates-header2")).toBeNull(); | |||
| }); | |||
| it("Should render", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("candidates-page")).toBeDefined(); | |||
| }); | |||
| it("Should render first button responsible for showing different components inside page because width of screen is greater than 600", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("all-white-btn")[0]).toBeDefined(); | |||
| }); | |||
| it("Should not render second button responsible for showing different components inside page because width of screen is greater than 600", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("candidate-btn-view-2")[0] | |||
| ).toBeUndefined(); | |||
| }); | |||
| it("should be rendered button which is used for showing input responsible for searching by name", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("candidate-btn")[1]).toBeDefined(); | |||
| }); | |||
| it("Should render first filter button because width is greater than 600", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("candidate-btn-filters1")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should not render second filter button because width is greater than 600", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("candidate-btn-filters2")[0] | |||
| ).toBeUndefined(); | |||
| }); | |||
| it("input for searching by name should not be shown when component is initialy rendered", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("proba")[0].style.visibility).toBe( | |||
| "hidden" | |||
| ); | |||
| }); | |||
| // it("input for searching by name should be shown after clicking button for first time", async () => { | |||
| // const { container } = render(cont); | |||
| // const button = container.getElementsByClassName("candidate-btn")[1]; | |||
| // const a = button.innerHTML; | |||
| // await waitFor(() => { | |||
| // fireEvent.click(button); | |||
| // expect( | |||
| // container.getElementsByClassName("proba")[0].style.visibility | |||
| // ).toBe("visible"); | |||
| // }); | |||
| // }); | |||
| it("Should render TableViewPage component when page is initialy rendered", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("candidates-table")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| // it("should render AdsCandidatesPage component when button for switching to another view is clicked for the first time", async () => { | |||
| // const { container } = render(cont); | |||
| // fireEvent.click(container.getElementsByClassName("candidate-btn")[0]); | |||
| // await waitFor(() => | |||
| // expect( | |||
| // container.getElementsByClassName("ads-candidates-container")[0] | |||
| // ).toBeDefined() | |||
| // ); | |||
| // }); | |||
| }); | |||
| @@ -0,0 +1,91 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { render, screen, fireEvent } from "@testing-library/react"; | |||
| import history from "../../store/utils/history"; | |||
| import ConfirmDialog from "../../components/MUI/ConfirmDialog"; | |||
| import mediaQuery from "css-mediaquery"; | |||
| function createMatchMedia(width) { | |||
| return (query) => ({ | |||
| matches: mediaQuery.match(query, { width }), | |||
| addListener: () => {}, | |||
| removeListener: () => {}, | |||
| }); | |||
| } | |||
| const onConfirm = jest.fn(); | |||
| const onClose = jest.fn(); | |||
| describe("ConfirmDialog render tests", () => { | |||
| var props = { | |||
| title: "title", | |||
| subtitle: "subtitle", | |||
| imageSrc: "path", | |||
| content: "content", | |||
| onConfirm: onConfirm, | |||
| onClose: onClose, | |||
| open: true, | |||
| maxWidth: "lg", | |||
| fullWidth: false, | |||
| responsive: true, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ConfirmDialog {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| beforeEach(() => { | |||
| // theme.breakpoints.down("md") will be true if width of screen is less than 900px | |||
| window.matchMedia = createMatchMedia(899); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("alert-container")).toBeDefined(); | |||
| }); | |||
| it("Should render full-screen elements because fullScreen is true", () => { | |||
| render(cont); | |||
| expect(screen.getAllByTestId("full-screen-elem").length).toBe(2); | |||
| }); | |||
| it("Should not render not-full-screen elements because fullScreen is true", () => { | |||
| render(cont); | |||
| expect(screen.queryByTestId("not-full-screen-elem")).toBeNull(); | |||
| }); | |||
| it("Should render content", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("modal-content")).toBeDefined(); | |||
| }); | |||
| it("Should not render button because fullScreen is true", () => { | |||
| render(cont); | |||
| expect(screen.queryByTestId("not-full-screen-btn")).toBeNull(); | |||
| }); | |||
| it("Should render confirm and and x-button", () => { | |||
| render(cont); | |||
| expect(screen.getAllByTestId("btn-testid").length).toBe(2); | |||
| }); | |||
| it("Should call onConfirm function once after clicking confirm button", () => { | |||
| render(cont); | |||
| fireEvent.click(screen.getAllByTestId("btn-testid")[1]); | |||
| expect(onConfirm.mock.calls).toHaveLength(1); | |||
| }); | |||
| it("Should call onClose function once after clicking Cancel button", () => { | |||
| render(cont); | |||
| fireEvent.click(screen.getAllByTestId("btn-testid")[0]); | |||
| expect(onClose.mock.calls).toHaveLength(1); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,86 @@ | |||
| import { render, screen, fireEvent } from "@testing-library/react"; | |||
| import * as redux from "react-redux"; | |||
| import CreateAdPage from "../../pages/AdsPage/CreateAdPage"; | |||
| import store from "../../store"; | |||
| import { mockState } from "../../mockState"; | |||
| import { Router } from "react-router-dom"; | |||
| import history from "../../store/utils/history"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| import CreateAdSecondStep from "../../pages/AdsPage/CreateAdSecondStep"; | |||
| describe("CreateAdPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ColorModeProvider> | |||
| <CreateAdPage /> | |||
| </ColorModeProvider> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue([ | |||
| { | |||
| technologyId: 1, | |||
| name: ".NET", | |||
| technologyType: "Backend", | |||
| isChecked: true, | |||
| }, | |||
| ]); | |||
| }); | |||
| afterEach(() => { | |||
| jest.resetAllMocks(); | |||
| }); | |||
| it("Should render create ad page", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("create-ad-page")).toBeDefined(); | |||
| }); | |||
| it("Should render go back button", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("create-ad-buttons-back")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render go forward button", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("create-ad-buttons-forward")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render create ad first step form", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("create-ad-first-step-form")).toBeDefined(); | |||
| }); | |||
| it("Should render sercond step form", () => { | |||
| const { container } = render(cont); | |||
| const formControls = container.getElementsByClassName( | |||
| "create-ad-form-control-first-step-input" | |||
| ); | |||
| fireEvent.change(formControls[0], { target: { value: ".NET DEVELOPER" } }); | |||
| fireEvent.change(formControls[1], { target: { value: "2020-05-24" } }); | |||
| fireEvent.click( | |||
| container.getElementsByClassName("create-ad-buttons-forward")[0] | |||
| ); | |||
| fireEvent.click(container.getElementsByClassName("create-ad-second-step-checkbox")[0]) | |||
| fireEvent.click( | |||
| container.getElementsByClassName("create-ad-buttons-forward")[0] | |||
| ); | |||
| expect(screen.getByTestId("create-ad-third-step-form")).toBeDefined(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,46 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render } from "@testing-library/react"; | |||
| import DayComponent from "../../components/Schedules/DayComponent"; | |||
| import history from "../../store/utils/history"; | |||
| const props = { | |||
| numberOfDay: 1, | |||
| nameOfDay: "sre", | |||
| interviews: mockState.schedule.schedule, | |||
| onClick: jest.fn(), | |||
| }; | |||
| describe("DayComponent render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <DayComponent {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("day-component-container")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should show only two interviews even if there is more interviews and span element which will tell us how many interviews is there", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("day-component-more")[0] | |||
| ).toBeDefined(); | |||
| expect( | |||
| container.getElementsByClassName("day-component-interviews-container") | |||
| .length | |||
| ).toBe(2); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,88 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { mockState } from "../../mockState"; | |||
| import { render, screen, fireEvent } from "@testing-library/react"; | |||
| import history from "../../store/utils/history"; | |||
| import DayDetailsComponent from "../../components/Schedules/DayDetailsComponent"; | |||
| import ColorModeProvider from "../../context/ColorModeContext"; | |||
| const setCurrentlySelected = jest.fn(); | |||
| const setCurrentlySelectedDay = jest.fn(); | |||
| const props = { | |||
| selectedDate: "20.12.2023", | |||
| selectionProcesses: mockState.schedule.schedule, | |||
| open: jest.fn(), | |||
| onClose: jest.fn(), | |||
| setCurrentlySelected: setCurrentlySelected, | |||
| setCurrentlySelectedDay: setCurrentlySelectedDay, | |||
| currentlySelectedDay: 20, | |||
| numberOfDaysInMonth: 31, | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/schedule", | |||
| }, | |||
| }, | |||
| }; | |||
| describe("DayDetailsComponent render tests", () => { | |||
| const cont = ( | |||
| <ColorModeProvider> | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <DayDetailsComponent {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| </ColorModeProvider> | |||
| ); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("day-component-dialog")).toBeDefined(); | |||
| }); | |||
| it("Should render left arrow as enabled because currenlty selected day is not 1", () => { | |||
| render(cont); | |||
| expect(screen.getAllByTestId("day-details-left-arrow")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render right arrow as enabled because currently selected day is not 31", () => { | |||
| render(cont); | |||
| expect(screen.getAllByTestId("day-details-right-arrow")[0]).toBeDefined(); | |||
| }); | |||
| it("Should show all interviews which we pass to component", () => { | |||
| render(cont); | |||
| expect(screen.getAllByTestId("day-details-component-process").length).toBe( | |||
| mockState.schedule.schedule.length | |||
| ); | |||
| }); | |||
| it("Should render candidate details page after clicking on candidate name", () => { | |||
| render(cont); | |||
| fireEvent.click(screen.getAllByTestId("day-details-applicant")[0]); | |||
| const arg = { pathname: "/candidates/1" }; | |||
| expect(props.history.push).toHaveBeenCalledWith(arg); | |||
| }); | |||
| it("Should call function when we press right arrow", () => { | |||
| render(cont); | |||
| fireEvent.click(screen.getAllByTestId("day-details-right-arrow")[0]); | |||
| expect(setCurrentlySelected.mock.calls).toHaveLength(1); | |||
| expect(setCurrentlySelectedDay.mock.calls).toHaveLength(1); | |||
| }); | |||
| it("Should call function when we press right arrow", () => { | |||
| render(cont); | |||
| fireEvent.click(screen.getAllByTestId("day-details-left-arrow")[0]); | |||
| expect(setCurrentlySelected.mock.calls).toHaveLength(1); | |||
| expect(setCurrentlySelectedDay.mock.calls).toHaveLength(1); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,48 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { render } from "@testing-library/react"; | |||
| import history from "../../store/utils/history"; | |||
| import ErrorPage from "../../pages/ErrorPages/ErrorPage"; | |||
| describe("ErrorPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ErrorPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| // beforeEach(() => { | |||
| // jest.mock("react-i18next", () => ({ | |||
| // useTranslation: () => ({ | |||
| // t: (key) => key, | |||
| // i18n: { changeLanguage: jest.fn() }, | |||
| // }), | |||
| // })); | |||
| // }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("c-error-page")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render status code 500", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("c-error-page__title")[0].textContent | |||
| ).toBe("500"); | |||
| }); | |||
| it("Should render text", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("c-error-page__text")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,69 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { render, screen } from "@testing-library/react"; | |||
| import history from "../../store/utils/history"; | |||
| import ForgotPasswordConfirmationPage from "../../pages/ForgotPasswordPage/ForgotPasswordConfirmationPageMUI"; | |||
| describe("ForgotPasswordConfirmationPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ForgotPasswordConfirmationPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("c-login-container")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render login logo", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("login-logo")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render header", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container | |||
| .getElementsByClassName("c-login-container")[0] | |||
| .querySelector("h") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render paragraph", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container | |||
| .getElementsByClassName("c-login-container")[0] | |||
| .querySelector("p") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should link for paragraph", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container | |||
| .getElementsByClassName("c-login-container")[0] | |||
| .querySelector("p") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render link for going to login page", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("back-link")).toBeDefined(); | |||
| }); | |||
| it("Should render dilig logo", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("dilig-logo")).toBeDefined(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,94 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { fireEvent, render, screen, waitFor } from "@testing-library/react"; | |||
| import history from "../../store/utils/history"; | |||
| import ForgotPasswordPage from "../../pages/ForgotPasswordPage/ForgotPasswordPageMUI"; | |||
| describe("ForgotPasswordPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <ForgotPasswordPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("c-login-container")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render login logo", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("login-logo")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render header", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container | |||
| .getElementsByClassName("c-login-container")[0] | |||
| .querySelector("h") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render paragraph", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container | |||
| .getElementsByClassName("c-login-container")[0] | |||
| .querySelector("p") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render email input", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("email-input")).toBeDefined(); | |||
| }); | |||
| it("Should render submit button", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("c-btn")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render link for going to login page", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("back-link")).toBeDefined(); | |||
| }); | |||
| it("Should render dilig logo", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("dilig-logo")).toBeDefined(); | |||
| }); | |||
| it("Should not dispatch function because input for email is empty", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(0)); | |||
| }); | |||
| it("Should dispatch function becxause input for email is not empty", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.change(screen.getByTestId("email-input"), { | |||
| target: { value: "dzenis@dilig.net" }, | |||
| }); | |||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(1)); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,69 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { render, screen, fireEvent } from "@testing-library/react"; | |||
| import history from "../../store/utils/history"; | |||
| import mediaQuery from "css-mediaquery"; | |||
| import InviteDialog from "../../components/MUI/InviteDialog"; | |||
| function createMatchMedia(width) { | |||
| return (query) => ({ | |||
| matches: mediaQuery.match(query, { width }), | |||
| addListener: () => {}, | |||
| removeListener: () => {}, | |||
| }); | |||
| } | |||
| const onClose = jest.fn(); | |||
| describe("ConfirmDialog render tests", () => { | |||
| var props = { | |||
| title: "title", | |||
| onClose: onClose, | |||
| open: true, | |||
| maxWidth: "lg", | |||
| fullWidth: false, | |||
| responsive: true, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <InviteDialog {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| beforeEach(() => { | |||
| // theme.breakpoints.down("md") will be true if width of screen is less than 900px | |||
| window.matchMedia = createMatchMedia(899); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("invite-dialog-container")).toBeDefined(); | |||
| }); | |||
| it("Should render title", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("invite-title")).toBeDefined(); | |||
| }); | |||
| it("Should render form", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("invite-form")).toBeDefined(); | |||
| }); | |||
| it("Should render three TextField elements", () => { | |||
| render(cont); | |||
| expect(screen.getAllByTestId("invite-input-text").length).toBe(3); | |||
| }); | |||
| it("Should render button for registration link", () => { | |||
| render(cont); | |||
| expect(screen.getAllByTestId("invite-btn")).toBeDefined(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,149 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { mockState } from "../../mockState"; | |||
| import { fireEvent, render, screen, waitFor } from "@testing-library/react"; | |||
| import history from "../../store/utils/history"; | |||
| import LoginPage from "../../pages/LoginPage/LoginPageMUI"; | |||
| describe("LoginPage render tests", () => { | |||
| var props = { | |||
| history: { | |||
| replace: jest.fn(), | |||
| push: jest.fn(), | |||
| location: { | |||
| pathname: "/", | |||
| }, | |||
| }, | |||
| }; | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <LoginPage {...props} /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| let spyOnUseSelector; | |||
| let spyOnUseDispatch; | |||
| let mockDispatch; | |||
| beforeEach(() => { | |||
| spyOnUseSelector = jest.spyOn(redux, "useSelector"); | |||
| spyOnUseSelector.mockReturnValue("some error"); | |||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||
| mockDispatch = jest.fn(); | |||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||
| }); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("c-login-container")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render login-logo", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("login-logo")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render welcome message", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container | |||
| .getElementsByClassName("c-login-container")[0] | |||
| .querySelector("h") | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render error message because we mocked error message", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("error-message")).toBeDefined(); | |||
| }); | |||
| it("Should render username input", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("username-input")).toBeDefined(); | |||
| }); | |||
| it("Should render password input", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("password-input")).toBeDefined(); | |||
| }); | |||
| it("Should render forgot paswword link", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("text-end")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render submit button", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("c-btn")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render separator container", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("separator")).toBeDefined(); | |||
| }); | |||
| it("Should dilig logo", () => { | |||
| render(cont); | |||
| expect(screen.getByTestId("dilig-logo")).toBeDefined(); | |||
| }); | |||
| it("Should not dispatch functions after clicking submit button because username and password inputs are emtpy", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(0)); | |||
| }); | |||
| it("Should not dispatch functions after clicking submit button because password input is emtpy", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.change(screen.getByTestId("username-input"), { | |||
| target: { value: "some username" }, | |||
| }); | |||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(0)); | |||
| }); | |||
| it("Should not dispatch functions after clicking submit button because username input is emtpy", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.change(screen.getByTestId("password-input"), { | |||
| target: { value: "some password" }, | |||
| }); | |||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(0)); | |||
| }); | |||
| it("Should dispatch two functions after clicking submit button", async () => { | |||
| const { container } = render(cont); | |||
| fireEvent.change(screen.getByTestId("username-input"), { | |||
| target: { value: "some username" }, | |||
| }); | |||
| fireEvent.change(screen.getByTestId("password-input"), { | |||
| target: { value: "some password" }, | |||
| }); | |||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(2)); | |||
| }); | |||
| // it("After clicking submit button we should go to ads page", async () => { | |||
| // const { container } = render(cont); | |||
| // fireEvent.change(screen.getByTestId("username-input"), { | |||
| // target: { value: "some username" }, | |||
| // }); | |||
| // fireEvent.change(screen.getByTestId("password-input"), { | |||
| // target: { value: "some password" }, | |||
| // }); | |||
| // fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||
| // const arg = { pathname: "/ads" }; | |||
| // expect(props.history.push).toHaveBeenCalledWith(arg); | |||
| // }); | |||
| }); | |||
| @@ -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() | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,34 @@ | |||
| import { render } from "@testing-library/react"; | |||
| import { Provider } from "react-redux"; | |||
| import { Router } from "react-router-dom"; | |||
| import NavbarComponent from "../../components/MUI/NavbarComponent"; | |||
| import store from "../../store"; | |||
| import history from "../../store/utils/history"; | |||
| jest.mock("react-router-dom", () => ({ | |||
| ...jest.requireActual("react-router-dom"), | |||
| useLocation: () => ({ | |||
| pathname: "localhost:3000/ads", | |||
| }), | |||
| })); | |||
| describe("navbar ui tests", () => { | |||
| beforeEach(() => {}); | |||
| const cont = ( | |||
| <Provider store={store}> | |||
| <Router history={history}> | |||
| <NavbarComponent /> | |||
| </Router> | |||
| </Provider> | |||
| ); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("should render", () => { | |||
| var {container} = render(cont); | |||
| expect(container.getElementsByClassName('text-blue')[0]).toBeDefined() | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,46 @@ | |||
| import * as redux from "react-redux"; | |||
| import store from "../../store"; | |||
| import { Router } from "react-router-dom"; | |||
| import { render } from "@testing-library/react"; | |||
| import history from "../../store/utils/history"; | |||
| import NotFoundPage from "../../pages/ErrorPages/NotFoundPage"; | |||
| describe("ErrorPage render tests", () => { | |||
| const cont = ( | |||
| <redux.Provider store={store}> | |||
| <Router history={history}> | |||
| <NotFoundPage /> | |||
| </Router> | |||
| </redux.Provider> | |||
| ); | |||
| afterEach(() => { | |||
| jest.restoreAllMocks(); | |||
| }); | |||
| it("Should render", () => { | |||
| const { container } = render(cont); | |||
| expect(container.getElementsByClassName("not-found-page")[0]).toBeDefined(); | |||
| }); | |||
| it("Should render status code 404", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("c-error-page__title")[0].textContent | |||
| ).toBe("404"); | |||
| }); | |||
| it("Should render text", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("c-error-page__text")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| it("Should render button for going back to previous page", () => { | |||
| const { container } = render(cont); | |||
| expect( | |||
| container.getElementsByClassName("c-error-page__button")[0] | |||
| ).toBeDefined(); | |||
| }); | |||
| }); | |||