Explorar el Código

Frontend initial commit

feature/added_docs_preview
bronjaermin hace 3 años
padre
commit
873eeaafc1
Se han modificado 100 ficheros con 59409 adiciones y 0 borrados
  1. 4
    0
      .dockerignore
  2. 2
    0
      .env
  3. 28
    0
      .eslintrc
  4. 22
    0
      .eslintrc.json
  5. 23
    0
      .gitignore
  6. 13
    0
      Dockerfile
  7. 15
    0
      db/db.js
  8. 8
    0
      nginx.conf
  9. 51132
    0
      package-lock.json
  10. 91
    0
      package.json
  11. BIN
      public/favicon.ico
  12. BIN
      public/hrcenter.png
  13. 50
    0
      public/index.html
  14. BIN
      public/logo192.png
  15. BIN
      public/logo512.png
  16. 25
    0
      public/manifest.json
  17. 3
    0
      public/robots.txt
  18. 38
    0
      src/App.css
  19. 25
    0
      src/App.js
  20. 109
    0
      src/AppRoutes.js
  21. 27
    0
      src/__tests__/ReduxTests/Reducers/ad/adReducer.test.js
  22. 46
    0
      src/__tests__/ReduxTests/Reducers/ad/adsReducer.test.js
  23. 26
    0
      src/__tests__/ReduxTests/Reducers/ad/archiveActiveAdReducer.test.js
  24. 30
    0
      src/__tests__/ReduxTests/Reducers/ad/archiveAdsReducer.test.js
  25. 30
    0
      src/__tests__/ReduxTests/Reducers/ad/createAdReducer.test.js
  26. 68
    0
      src/__tests__/ReduxTests/Reducers/addAddTechnologiesReducer.test.js
  27. 26
    0
      src/__tests__/ReduxTests/Reducers/applyForAdReducer.test.js
  28. 35
    0
      src/__tests__/ReduxTests/Reducers/candidateOptionsReducer.test.js
  29. 75
    0
      src/__tests__/ReduxTests/Reducers/candidateReducer.test.js
  30. 66
    0
      src/__tests__/ReduxTests/Reducers/candidatesReducer.test.js
  31. 29
    0
      src/__tests__/ReduxTests/Reducers/initProccesReducer.test.js
  32. 26
    0
      src/__tests__/ReduxTests/Reducers/inviteUserReducer.test.js
  33. 25
    0
      src/__tests__/ReduxTests/Reducers/loadingReducer.test.js
  34. 55
    0
      src/__tests__/ReduxTests/Reducers/loginReducer.test.js
  35. 32
    0
      src/__tests__/ReduxTests/Reducers/patterns/createPatternReducer.test.js
  36. 32
    0
      src/__tests__/ReduxTests/Reducers/patterns/patternApplicantsReducer.test.js
  37. 32
    0
      src/__tests__/ReduxTests/Reducers/patterns/patternReducer.test.js
  38. 50
    0
      src/__tests__/ReduxTests/Reducers/patterns/patternsReducer.test.js
  39. 51
    0
      src/__tests__/ReduxTests/Reducers/patterns/scheduleAppointmentReducer.test.js
  40. 32
    0
      src/__tests__/ReduxTests/Reducers/patterns/updatePatternReducer.test.js
  41. 32
    0
      src/__tests__/ReduxTests/Reducers/processes/applicantWithProcessesReducer.test.js
  42. 37
    0
      src/__tests__/ReduxTests/Reducers/processes/interviewerUpdateReducer.test.js
  43. 36
    0
      src/__tests__/ReduxTests/Reducers/processes/processReducer.test.js
  44. 32
    0
      src/__tests__/ReduxTests/Reducers/processes/processesReducer.test.js
  45. 66
    0
      src/__tests__/ReduxTests/Reducers/processes/statusReducer.test.js
  46. 37
    0
      src/__tests__/ReduxTests/Reducers/processes/statusUpdateReducer.test.js
  47. 22
    0
      src/__tests__/ReduxTests/Reducers/registerReducer.test.js
  48. 22
    0
      src/__tests__/ReduxTests/Reducers/scheduleReducer.test.js
  49. 21
    0
      src/__tests__/ReduxTests/Reducers/screeningTestsReducer.test.js
  50. 29
    0
      src/__tests__/ReduxTests/Reducers/statsReducer.test.js
  51. 34
    0
      src/__tests__/ReduxTests/Reducers/statusUpdateReducer.test.js
  52. 66
    0
      src/__tests__/ReduxTests/Reducers/technologiesReducer.test.js
  53. 47
    0
      src/__tests__/ReduxTests/Reducers/userDetailsReducer.test.js
  54. 46
    0
      src/__tests__/ReduxTests/Reducers/userReducer.test.js
  55. 104
    0
      src/__tests__/ReduxTests/Reducers/usersReducer.test.js
  56. 106
    0
      src/__tests__/ReduxTests/adsCandidatesPageReducer.test.js
  57. 407
    0
      src/__tests__/ReduxTests/adsReducer.test.js
  58. 103
    0
      src/__tests__/ReduxTests/applicantsSaga.test.js
  59. 182
    0
      src/__tests__/ReduxTests/candidateDetailsPageReducer.test.js
  60. 91
    0
      src/__tests__/ReduxTests/candidatesPageReducer.test.js
  61. 407
    0
      src/__tests__/ReduxTests/candidatesSaga.test.js
  62. 245
    0
      src/__tests__/ReduxTests/inviteDialog.test.js
  63. 478
    0
      src/__tests__/ReduxTests/loginSaga.test.js
  64. 431
    0
      src/__tests__/ReduxTests/patternsReducer.test.js
  65. 566
    0
      src/__tests__/ReduxTests/processesReducer.test.js
  66. 136
    0
      src/__tests__/ReduxTests/registerSagaTest.test.js
  67. 112
    0
      src/__tests__/ReduxTests/schedulePageReducer.test.js
  68. 109
    0
      src/__tests__/ReduxTests/screeningTestsSaga.test.js
  69. 97
    0
      src/__tests__/ReduxTests/statsPageReducer.test.js
  70. 127
    0
      src/__tests__/ReduxTests/tableViewPageReducer.test.js
  71. 108
    0
      src/__tests__/ReduxTests/userDetailsReducer.test.js
  72. 211
    0
      src/__tests__/ReduxTests/userManagementReducer.test.js
  73. 96
    0
      src/__tests__/ReduxTests/usersPageReducer.test.js
  74. 80
    0
      src/__tests__/UITests/SelectionCardUI.test.js
  75. 143
    0
      src/__tests__/UITests/SelectionComponentUI.test.js
  76. 62
    0
      src/__tests__/UITests/adDetailsCandidateCardUI.test.js
  77. 104
    0
      src/__tests__/UITests/adDetailsPageUI.test.js
  78. 101
    0
      src/__tests__/UITests/adsCandidatesPageUI.test.js
  79. 154
    0
      src/__tests__/UITests/adsPageUI.test.js
  80. 53
    0
      src/__tests__/UITests/applicantSelectionPage.test.js
  81. 110
    0
      src/__tests__/UITests/applyForAdFirstStageUI.test.js
  82. 106
    0
      src/__tests__/UITests/applyForAdFourthStageUI.test.js
  83. 125
    0
      src/__tests__/UITests/applyForAdSecondStageUI.test.js
  84. 110
    0
      src/__tests__/UITests/applyForAdThirdStageUI.test.js
  85. 199
    0
      src/__tests__/UITests/candidateDetailsPageUI.test.js
  86. 72
    0
      src/__tests__/UITests/candidateFilterUI.test.js
  87. 120
    0
      src/__tests__/UITests/candidatesPageUI.test.js
  88. 91
    0
      src/__tests__/UITests/confirmDialogComponentUI.test.js
  89. 86
    0
      src/__tests__/UITests/createAdPageUI.test.js
  90. 46
    0
      src/__tests__/UITests/dayComponentUI.test.js
  91. 88
    0
      src/__tests__/UITests/dayDetailsComponentUI.test.js
  92. 48
    0
      src/__tests__/UITests/errorPageUI.test.js
  93. 69
    0
      src/__tests__/UITests/forgotPasswordConfirmationPageUI.test.js
  94. 94
    0
      src/__tests__/UITests/forgotPasswordPageUI.test.js
  95. 69
    0
      src/__tests__/UITests/inviteDialogComponentUI.test.js
  96. 149
    0
      src/__tests__/UITests/loginPageUI.test.js
  97. 26
    0
      src/__tests__/UITests/mainContainer.test.js
  98. 34
    0
      src/__tests__/UITests/navbar.test.js
  99. 46
    0
      src/__tests__/UITests/notFoundPageUI.test.js
  100. 0
    0
      src/__tests__/UITests/patternDetailsPageUI.test.js

+ 4
- 0
.dockerignore Ver fichero

@@ -0,0 +1,4 @@
node_modules
npm-debug.log
build
.dockerignore

+ 2
- 0
.env Ver fichero

@@ -0,0 +1,2 @@

REACT_APP_BASE_API_URL=https://portalgatewayapi.bullioninternational.info/

+ 28
- 0
.eslintrc Ver fichero

@@ -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"
}]
}
}

+ 22
- 0
.eslintrc.json Ver fichero

@@ -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": {
}
}

+ 23
- 0
.gitignore Ver fichero

@@ -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*

+ 13
- 0
Dockerfile Ver fichero

@@ -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;"]

+ 15
- 0
db/db.js Ver fichero

@@ -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 };
};

+ 8
- 0
nginx.conf Ver fichero

@@ -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;
}
}

+ 51132
- 0
package-lock.json
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 91
- 0
package.json Ver fichero

@@ -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"
}
}

BIN
public/favicon.ico Ver fichero


BIN
public/hrcenter.png Ver fichero


+ 50
- 0
public/index.html Ver fichero

@@ -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>

BIN
public/logo192.png Ver fichero


BIN
public/logo512.png Ver fichero


+ 25
- 0
public/manifest.json Ver fichero

@@ -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"
}

+ 3
- 0
public/robots.txt Ver fichero

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

+ 38
- 0
src/App.css Ver fichero

@@ -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);
}
}

+ 25
- 0
src/App.js Ver fichero

@@ -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;

+ 109
- 0
src/AppRoutes.js Ver fichero

@@ -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;

+ 27
- 0
src/__tests__/ReduxTests/Reducers/ad/adReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 46
- 0
src/__tests__/ReduxTests/Reducers/ad/adsReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 26
- 0
src/__tests__/ReduxTests/Reducers/ad/archiveActiveAdReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 30
- 0
src/__tests__/ReduxTests/Reducers/ad/archiveAdsReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 30
- 0
src/__tests__/ReduxTests/Reducers/ad/createAdReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 68
- 0
src/__tests__/ReduxTests/Reducers/addAddTechnologiesReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 26
- 0
src/__tests__/ReduxTests/Reducers/applyForAdReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 35
- 0
src/__tests__/ReduxTests/Reducers/candidateOptionsReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 75
- 0
src/__tests__/ReduxTests/Reducers/candidateReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 66
- 0
src/__tests__/ReduxTests/Reducers/candidatesReducer.test.js Ver fichero

@@ -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,
});
});
});

+ 29
- 0
src/__tests__/ReduxTests/Reducers/initProccesReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 26
- 0
src/__tests__/ReduxTests/Reducers/inviteUserReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 25
- 0
src/__tests__/ReduxTests/Reducers/loadingReducer.test.js Ver fichero

@@ -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,
});
});
});

+ 55
- 0
src/__tests__/ReduxTests/Reducers/loginReducer.test.js Ver fichero

@@ -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",
});
});
});

+ 32
- 0
src/__tests__/ReduxTests/Reducers/patterns/createPatternReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 32
- 0
src/__tests__/ReduxTests/Reducers/patterns/patternApplicantsReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 32
- 0
src/__tests__/ReduxTests/Reducers/patterns/patternReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 50
- 0
src/__tests__/ReduxTests/Reducers/patterns/patternsReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 51
- 0
src/__tests__/ReduxTests/Reducers/patterns/scheduleAppointmentReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 32
- 0
src/__tests__/ReduxTests/Reducers/patterns/updatePatternReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 32
- 0
src/__tests__/ReduxTests/Reducers/processes/applicantWithProcessesReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 37
- 0
src/__tests__/ReduxTests/Reducers/processes/interviewerUpdateReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 36
- 0
src/__tests__/ReduxTests/Reducers/processes/processReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 32
- 0
src/__tests__/ReduxTests/Reducers/processes/processesReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 66
- 0
src/__tests__/ReduxTests/Reducers/processes/statusReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 37
- 0
src/__tests__/ReduxTests/Reducers/processes/statusUpdateReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 22
- 0
src/__tests__/ReduxTests/Reducers/registerReducer.test.js Ver fichero

@@ -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",
});
});
});

+ 22
- 0
src/__tests__/ReduxTests/Reducers/scheduleReducer.test.js Ver fichero

@@ -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",
});
});
});

+ 21
- 0
src/__tests__/ReduxTests/Reducers/screeningTestsReducer.test.js Ver fichero

@@ -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",
});
});
});

+ 29
- 0
src/__tests__/ReduxTests/Reducers/statsReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 34
- 0
src/__tests__/ReduxTests/Reducers/statusUpdateReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 66
- 0
src/__tests__/ReduxTests/Reducers/technologiesReducer.test.js Ver fichero

@@ -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: "",
});
});
});

+ 47
- 0
src/__tests__/ReduxTests/Reducers/userDetailsReducer.test.js Ver fichero

@@ -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: "",
});
});

+ 46
- 0
src/__tests__/ReduxTests/Reducers/userReducer.test.js Ver fichero

@@ -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",
});
});
});

+ 104
- 0
src/__tests__/ReduxTests/Reducers/usersReducer.test.js Ver fichero

@@ -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 }],
});
});
});

+ 106
- 0
src/__tests__/ReduxTests/adsCandidatesPageReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 407
- 0
src/__tests__/ReduxTests/adsReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 103
- 0
src/__tests__/ReduxTests/applicantsSaga.test.js Ver fichero

@@ -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"));
});
});

+ 182
- 0
src/__tests__/ReduxTests/candidateDetailsPageReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 91
- 0
src/__tests__/ReduxTests/candidatesPageReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 407
- 0
src/__tests__/ReduxTests/candidatesSaga.test.js Ver fichero

@@ -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"));
});
});

+ 245
- 0
src/__tests__/ReduxTests/inviteDialog.test.js Ver fichero

@@ -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")
);
});
});

+ 478
- 0
src/__tests__/ReduxTests/loginSaga.test.js Ver fichero

@@ -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));
});
});

+ 431
- 0
src/__tests__/ReduxTests/patternsReducer.test.js Ver fichero

@@ -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();
});
});

+ 566
- 0
src/__tests__/ReduxTests/processesReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 136
- 0
src/__tests__/ReduxTests/registerSagaTest.test.js Ver fichero

@@ -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"));
});
});

+ 112
- 0
src/__tests__/ReduxTests/schedulePageReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 109
- 0
src/__tests__/ReduxTests/screeningTestsSaga.test.js Ver fichero

@@ -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"));
});
});

+ 97
- 0
src/__tests__/ReduxTests/statsPageReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 127
- 0
src/__tests__/ReduxTests/tableViewPageReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 108
- 0
src/__tests__/ReduxTests/userDetailsReducer.test.js Ver fichero

@@ -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"));
});
});

+ 211
- 0
src/__tests__/ReduxTests/userManagementReducer.test.js Ver fichero

@@ -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"));
});
});

+ 96
- 0
src/__tests__/ReduxTests/usersPageReducer.test.js Ver fichero

@@ -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)
);
});
});

+ 80
- 0
src/__tests__/UITests/SelectionCardUI.test.js Ver fichero

@@ -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,
// })
// );
// });
});

+ 143
- 0
src/__tests__/UITests/SelectionComponentUI.test.js Ver fichero

@@ -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);
});
});

+ 62
- 0
src/__tests__/UITests/adDetailsCandidateCardUI.test.js Ver fichero

@@ -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");
});
});
});

+ 104
- 0
src/__tests__/UITests/adDetailsPageUI.test.js Ver fichero

@@ -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));
});
});

+ 101
- 0
src/__tests__/UITests/adsCandidatesPageUI.test.js Ver fichero

@@ -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);
});
});

+ 154
- 0
src/__tests__/UITests/adsPageUI.test.js Ver fichero

@@ -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");
});
});

+ 53
- 0
src/__tests__/UITests/applicantSelectionPage.test.js Ver fichero

@@ -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();
// });
});

+ 110
- 0
src/__tests__/UITests/applyForAdFirstStageUI.test.js Ver fichero

@@ -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());
});
});

+ 106
- 0
src/__tests__/UITests/applyForAdFourthStageUI.test.js Ver fichero

@@ -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] },
});
});
});

+ 125
- 0
src/__tests__/UITests/applyForAdSecondStageUI.test.js Ver fichero

@@ -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));
});
});

+ 110
- 0
src/__tests__/UITests/applyForAdThirdStageUI.test.js Ver fichero

@@ -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());
});
});

+ 199
- 0
src/__tests__/UITests/candidateDetailsPageUI.test.js Ver fichero

@@ -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);
});
});

+ 72
- 0
src/__tests__/UITests/candidateFilterUI.test.js Ver fichero

@@ -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();
});
});
});

+ 120
- 0
src/__tests__/UITests/candidatesPageUI.test.js Ver fichero

@@ -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()
// );
// });
});

+ 91
- 0
src/__tests__/UITests/confirmDialogComponentUI.test.js Ver fichero

@@ -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);
});
});

+ 86
- 0
src/__tests__/UITests/createAdPageUI.test.js Ver fichero

@@ -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();
});
});

+ 46
- 0
src/__tests__/UITests/dayComponentUI.test.js Ver fichero

@@ -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);
});
});

+ 88
- 0
src/__tests__/UITests/dayDetailsComponentUI.test.js Ver fichero

@@ -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);
});
});

+ 48
- 0
src/__tests__/UITests/errorPageUI.test.js Ver fichero

@@ -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();
});
});

+ 69
- 0
src/__tests__/UITests/forgotPasswordConfirmationPageUI.test.js Ver fichero

@@ -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();
});
});

+ 94
- 0
src/__tests__/UITests/forgotPasswordPageUI.test.js Ver fichero

@@ -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));
});
});

+ 69
- 0
src/__tests__/UITests/inviteDialogComponentUI.test.js Ver fichero

@@ -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();
});
});

+ 149
- 0
src/__tests__/UITests/loginPageUI.test.js Ver fichero

@@ -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);
// });
});

+ 26
- 0
src/__tests__/UITests/mainContainer.test.js Ver fichero

@@ -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()
});
});

+ 34
- 0
src/__tests__/UITests/navbar.test.js Ver fichero

@@ -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()
});
});

+ 46
- 0
src/__tests__/UITests/notFoundPageUI.test.js Ver fichero

@@ -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();
});
});

+ 0
- 0
src/__tests__/UITests/patternDetailsPageUI.test.js Ver fichero


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio

Cargando…
Cancelar
Guardar