Просмотр исходного кода

Merge branch 'feature/unit_tests_candidates_saga' of Neca/HRCenter into FE_dev

pull/178/head
safet.purkovic 3 лет назад
Родитель
Сommit
9c26878be3

+ 407
- 0
src/__tests__/ReduxTests/candidatesSaga.test.js Просмотреть файл

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

+ 4
- 2
src/__tests__/UITests/candidateDetailsPageUI.test.js Просмотреть файл

@@ -115,7 +115,7 @@ describe("CandidateDetailsPage render tests", () => {
expect(container.getElementsByClassName("comment-input")[0]).toBeDefined();
});

it("Initially mention should not be rendered", async () => {
it("Initially mention should not be rendered", async () => {
const { container } = render(cont);
await waitFor(() =>
expect(
@@ -132,7 +132,9 @@ describe("CandidateDetailsPage render tests", () => {
// fireEvent.change(input, { target: { value: "@" } });
// await waitFor(() =>
// expect(
// container.getElementsByClassName("comment-input_suggestions")[0]
// container
// .getElementsByClassName("comment-input")[0]
// .getElementsByClassName("comment-input_suggestions")[0]
// ).toBeDefined()
// );
// });

+ 63
- 0
src/__tests__/UITests/interviewDialogComponent.test.js Просмотреть файл

@@ -0,0 +1,63 @@
import * as redux from "react-redux";
import store from "../../store";
import { Router } from "react-router-dom";
import { mockState } from "../../mockState";
import { render, screen, waitFor } from "@testing-library/react";
import history from "../../store/utils/history";
import mediaQuery from "css-mediaquery";
import InterviewDialog from "../../components/MUI/InterviewDialog";

const props = {
title: "title",
subtitle: "subtitle",
imgSrc: "imgSrc",
onClose: jest.fn(),
open: true,
maxWidth: "xl",
fullWidth: true,
responsive: true,
};

function createMatchMedia(width) {
return (query) => ({
matches: mediaQuery.match(query, { width }),
addListener: () => {},
removeListener: () => {},
});
}

describe("InterviewDialog render tests", () => {
const cont = (
<redux.Provider store={store}>
<Router history={history}>
<InterviewDialog {...props} />
</Router>
</redux.Provider>
);

let spyOnUseSelector;
let spyOnUseDispatch;
let mockDispatch;

beforeEach(() => {
window.matchMedia = createMatchMedia(362);
spyOnUseSelector = jest.spyOn(redux, "useSelector");
spyOnUseSelector
.mockReturnValueOnce(mockState.options)
.mockReturnValueOnce(mockState.users)
.mockReturnValueOnce(mockState.initProcess);

spyOnUseDispatch = jest.spyOn(redux, "useDispatch");
mockDispatch = jest.fn();
spyOnUseDispatch.mockReturnValue(mockDispatch);
});

afterEach(() => {
jest.restoreAllMocks();
});

it("Should render", async () => {
render(cont);
waitFor(() => expect(screen.getByTestId("interview-dialog")).toBeDefined());
});
});

+ 0
- 24
src/__tests__/UITests/loginPageUI.test.js Просмотреть файл

@@ -6,30 +6,6 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import history from "../../store/utils/history";
import LoginPage from "../../pages/LoginPage/LoginPageMUI";

// class LocalStorageMock {
// constructor() {
// this.store = {};
// }

// clear() {
// this.store = {};
// }

// getItem(key) {
// return undefined;
// }

// setItem(key, value) {
// this.store[key] = String(value);
// }

// removeItem(key) {
// delete this.store[key];
// }
// }

// global.localStorage = new LocalStorageMock;

describe("LoginPage render tests", () => {
var props = {
history: {

+ 71
- 0
src/__tests__/UITests/statusDialogComponentUI.test.js Просмотреть файл

@@ -0,0 +1,71 @@
import * as redux from "react-redux";
import store from "../../store";
import { Router } from "react-router-dom";
import { mockState } from "../../mockState";
import { render, screen, waitFor } from "@testing-library/react";
import history from "../../store/utils/history";
import StatusDialog from "../../components/MUI/StatusDialog";
import mediaQuery from "css-mediaquery";
import { SelectionContext } from "../../context/SelectionContext";

const props = {
title: "title",
subtitle: "subtitle",
imgSrc: "imgSrc",
onClose: jest.fn(),
open: true,
maxWidth: "xl",
fullWidth: true,
responsive: true,
};

function createMatchMedia(width) {
return (query) => ({
matches: mediaQuery.match(query, { width }),
addListener: () => {},
removeListener: () => {},
});
}

describe("Statusialog render tests", () => {
const cont = (
<redux.Provider store={store}>
<SelectionContext.Provider
value={{
selectionProcess: {},
activeProcess: { process: { selectionLevelId: 2 } },
}}
>
<Router history={history}>
<StatusDialog {...props} />
</Router>
</SelectionContext.Provider>
</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.initProcess)
.mockReturnValueOnce(mockState.screeningTests);

spyOnUseDispatch = jest.spyOn(redux, "useDispatch");
mockDispatch = jest.fn();
spyOnUseDispatch.mockReturnValue(mockDispatch);
});

afterEach(() => {
jest.restoreAllMocks();
});

it("Should render", async () => {
render(cont);
waitFor(() => expect(screen.getByTestId("status-dialog")).toBeDefined());
});
});

+ 2
- 2
src/components/MUI/StatusDialog.js Просмотреть файл

@@ -46,7 +46,6 @@ const StatusDialog = ({

const theme = useTheme();
const fullScreen = useMediaQuery(theme.breakpoints.down("md"));

const { users } = useSelector((s) => s.users);
const { isSuccess } = useSelector((s) => s.initProcess);
const { screeningTests } = useSelector((s) => s.screeningTests);
@@ -135,12 +134,13 @@ const StatusDialog = ({
fullWidth={fullWidth}
fullScreen={responsive && fullScreen}
onClose={handleClose}
data-testid="status-dialog"
open={open}
style={{
padding: "36px",
}}
>
<div style={{ padding: "36px" }}>
<div style={{ padding: "36px" }} data-testid="status-dialog">
<DialogTitle style={{ padding: 0 }}>
{fullScreen ? (
<>

+ 18
- 3
src/mockState.js Просмотреть файл

@@ -1,5 +1,20 @@
/* istanbul ignore file */
export const mockState = {
initProcess: {
isSuccess: false,
},
screeningTests: {
screeningTests: [],
},
options: {
options: [
{
applicantId: 1,
firstName: "Dzenis",
lastName: "Hadzifejzovic",
},
],
},
user: {
user: {
id: 1,
@@ -1032,7 +1047,7 @@ export const mockState = {
comment: null,
date: "2023-01-21T01:05:00",
link: null,
scheduler: null
scheduler: null,
},
{
selectionLevel: { id: 3, name: "Tehnički intervju" },
@@ -1040,7 +1055,7 @@ export const mockState = {
comment: null,
date: "2023-01-21T01:05:00",
link: null,
scheduler: null
scheduler: null,
},
{
selectionLevel: { id: 4, name: "Konačna odluka" },
@@ -1048,7 +1063,7 @@ export const mockState = {
comment: null,
date: "2023-01-21T01:05:00",
link: null,
scheduler: null
scheduler: null,
},
],
technologyApplicants: [],

+ 0
- 32
src/store/selectors/randomDataSelectors.js Просмотреть файл

@@ -1,32 +0,0 @@
import { createSelector } from 'reselect';

const randomDataSelector = (state) => state.randomData;

export const itemsSelector = createSelector(randomDataSelector, (state) =>
(state.filter) ? state.filteredItems : state.items
);

export const pageSelector = createSelector(
randomDataSelector,
(state) => state.page
);

export const itemsPerPageSelector = createSelector(
randomDataSelector,
(state) => state.itemsPerPage
);

export const countSelector = createSelector(
randomDataSelector,
(state) => state.count
);

export const filterSelector = createSelector(
randomDataSelector,
(state) => state.filter
);

export const sortSelector = createSelector(
randomDataSelector,
(state) => state.sort
);

Загрузка…
Отмена
Сохранить