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

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

pull/116/head
safet.purkovic 3 лет назад
Родитель
Сommit
189f840fb1

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

@@ -0,0 +1,68 @@
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 { registerSuccess } from "../../store/actions/register/registerActions";
import { runSaga } from "redux-saga";
import { userDetails } from "../../store/saga/usersSaga";
import { registerUser } from "../../store/saga/registerSaga";

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: {
password:'',
email:'',
confirm:'',
position:'',
linkedIn:'',
phone:'',
token:'',
},
}).done;

expect(api.register.mock.calls.length).toBe(1);
expect(dispatchedActions).toContainEqual(registerSuccess());
});
});

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

@@ -0,0 +1,83 @@
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 } from "../../store/actions/users/usersActions";
import { runSaga } from "redux-saga";

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

await runSaga(fakeStore, userDetails, {
payload: {
id: 1,
},
}).done;

expect(api.userDetailsRequest.mock.calls.length).toBe(1);
expect(dispatchedActions).toContainEqual(stateUserDetailsSuccess(mockState.user.user));
});
});

+ 74
- 10
src/__tests__/ReduxTests/userManagementReducer.test.js Просмотреть файл

@@ -8,11 +8,17 @@ 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 } from "../../store/saga/usersSaga";
import { useTranslation } from 'react-i18next';
import {
deleteStateUser,
setEnableUsers,
setUsers,
setUsersError,
toggleSingleUser,
} from "../../store/actions/users/usersActions";
import { deleteUser, enableUser, getUsers } from "../../store/saga/usersSaga";
import { useTranslation } from "react-i18next";

describe("Stats reducer tests", () => {
describe("User management reducer tests", () => {
const cont = (
<redux.Provider store={store}>
<Router history={history}>
@@ -52,10 +58,10 @@ describe("Stats reducer tests", () => {
it("should handle users 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 } },
response: {
data: { message: mockState.selections.fetchSelectionsErrorMessage },
},
};
api.getAllUsers = jest.fn(() => Promise.reject(error));

@@ -67,8 +73,66 @@ describe("Stats reducer tests", () => {
await runSaga(fakeStore, getUsers).done;

expect(api.getAllUsers.mock.calls.length).toBe(1);
expect(dispatchedActions).toContainEqual(
setUsersError(undefined)
);
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),
};

await runSaga(fakeStore, enableUser, {
payload: {
id: 1,
},
}).done;

expect(api.enableUserRequest.mock.calls.length).toBe(1);
expect(dispatchedActions).toContainEqual(setEnableUsers());
expect(dispatchedActions).toContainEqual(toggleSingleUser());
});

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

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

@@ -0,0 +1,53 @@
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, screen, fireEvent, waitFor } from "@testing-library/react";
import RegisterPage from "../../pages/RegisterPage/RegisterPage";
import { FormProvider } from "../../context/FormContext";

const token =''
const mail = "";

const mockHistoryPush = jest.fn();

jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useHistory: () => ({
push: mockHistoryPush,
}),
useLocation: () => ({
search: `/register?token=${token}&email=${mail}`,
}),
}));

describe("Register page tests", () => {
var props = {
history: {
replace: jest.fn(),
push: jest.fn(),
location: {
pathname: "",
},
},
};
const cont = (
<FormProvider>
<redux.Provider store={store}>
<Router history={history}>
<RegisterPage {...props} />
</Router>
</redux.Provider>
</FormProvider>
);

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

it("Should render error message", () => {
render(cont);
expect(screen.getByTestId("error-h")).toBeDefined();
});
});

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

@@ -0,0 +1,90 @@
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, screen, fireEvent, waitFor } from "@testing-library/react";
import RegisterPage from "../../pages/RegisterPage/RegisterPage";
import { FormProvider } from "../../context/FormContext";

const token =
"CfDJ8N77hhxpq99AuN1MAz9yxEG4HLGzmqe2fKGnXq8%2b3IWmhUdA3BZfaRAyhqLgUA%2fTAKarHSos484YEGrm13edjQbYXboYRnzXfEBdrhdAO5yFiEoij24x6k9os6JVfIiCVDfEmAA9zS23zaTqak9URTkUxYk4%2fsxR0DyE4YFqH485q%2fvIG0flGlotuHyLeE5i%2bQ%3d%3d";
const mail = "jest@dilig.net";

const mockHistoryPush = jest.fn();

jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useHistory: () => ({
push: mockHistoryPush,
}),
useLocation: () => ({
search: `/register?token=${token}&email=${mail}`,
}),
}));

describe("Register page tests", () => {
var props = {
history: {
replace: jest.fn(),
push: jest.fn(),
location: {
pathname: "",
},
},
};
const cont = (
<FormProvider>
<redux.Provider store={store}>
<Router history={history}>
<RegisterPage {...props} />
</Router>
</redux.Provider>
</FormProvider>
);

// let spyOnUseSelector;
// let spyOnUseDispatch;
// let mockDispatch;

beforeEach(() => {
//
});

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

it("Should render", () => {
render(cont);
expect(screen.getByTestId("btn")).toBeDefined();
});

it("Email input should have default value", () => {
render(cont);
expect(screen.getByTestId("reg-input-1").value).toBe("jest@dilig.net");
});

it("Email input should be disabled by default", () => {
render(cont);
expect(screen.getByTestId("reg-input-1")).toHaveAttribute("disabled");
});

it("Should show second step form after submiting first", async () => {
render(cont);

fireEvent.change(screen.getByTestId("reg-input-2"), {
target: { value: "Password123!" },
});
fireEvent.change(screen.getByTestId("reg-input-3"), {
target: { value: "Password123!" },
});

fireEvent.click(screen.getByTestId("btn"));

// waiting for formik validation
await waitFor(() =>
expect(screen.getByTestId("reg-input-4")).toBeDefined()
);
});
});

+ 3
- 0
src/components/Registration/FirstStepForm.js Просмотреть файл

@@ -94,6 +94,7 @@ function FirstStepForm() {
margin="normal"
disabled
fullWidth
inputProps={{ "data-testid": "reg-input-1" }}
value={formik.values.email}
onChange={formik.handleChange}
error={formik.touched.email && Boolean(formik.errors.email)}
@@ -106,6 +107,7 @@ function FirstStepForm() {
margin="normal"
type={showPassword ? "text" : "password"}
fullWidth
inputProps={{ "data-testid": "reg-input-2" }}
onChange={formik.handleChange}
error={formik.touched.password && Boolean(formik.errors.password)}
helperText={formik.touched.password && formik.errors.password}
@@ -129,6 +131,7 @@ function FirstStepForm() {
margin="normal"
type={showPassword ? "text" : "password"}
fullWidth
inputProps={{ "data-testid": "reg-input-3" }}
onChange={formik.handleChange}
error={formik.touched.confirm && Boolean(formik.errors.confirm)}
helperText={formik.touched.confirm && formik.errors.confirm}

+ 3
- 0
src/components/Registration/SecondStepForm.js Просмотреть файл

@@ -70,12 +70,14 @@ function SecondStepForm() {
label={t("registration.phone")}
margin="normal"
fullWidth
inputProps={{ "data-testid": "reg-input-4" }}
onChange={formik.handleChange}
error={formik.touched.phone && Boolean(formik.errors.phone)}
helperText={formik.touched.phone && formik.errors.phone}
/>
<TextField
name="position"
inputProps={{ "data-testid": "reg-input-5" }}
label={t("registration.position")}
margin="normal"
fullWidth
@@ -85,6 +87,7 @@ function SecondStepForm() {
/>
<TextField
name="linkedin"
inputProps={{ "data-testid": "reg-input-6" }}
label={t("registration.linkedinProfile")}
margin="normal"
fullWidth

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

@@ -1,4 +1,18 @@
export const mockState = {
user: {
user: {
id: 1,
firstName: "User",
lastName: "User",
email: "user.user@dilig.net",
isEnabled: true,
phoneNumber: "123123",
position: "ss",
linkedIn: "ss",
},
errorMessage: "",
},
schedule: {
schedule: [
{

+ 1
- 2
src/pages/RegisterPage/RegisterPage.js Просмотреть файл

@@ -97,7 +97,6 @@ const RegisterPage = ({ history }) => {
<>
<Container
component="main"
maxWidth="xl"
className="c-login-container"
fullwidth="true"
>
@@ -146,7 +145,7 @@ const RegisterPage = ({ history }) => {
<Step />
</>
) : (
<h3 style={{ margin: "50px 0px" }}>There was a mistake...</h3>
<h3 data-testid='error-h' style={{ margin: "50px 0px" }}>There was a mistake...</h3>
)}
</Box>
</Container>

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