Selaa lähdekoodia

added login saga tests

pull/174/head
meris.ahmatovic 3 vuotta sitten
vanhempi
commit
8739b88942

+ 478
- 0
src/__tests__/ReduxTests/loginSaga.test.js Näytä tiedosto

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

+ 53
- 0
src/__tests__/UITests/applicantSelectionPage.test.js Näytä tiedosto

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

+ 34
- 0
src/__tests__/UITests/navbar.test.js Näytä tiedosto

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

+ 1
- 1
src/components/Selection/ApplicantSelection.js Näytä tiedosto

@@ -17,7 +17,7 @@ const ApplicantSelection = ({
className,
}) => {
return (
<div className={`active-process-card ${className}`} onClick={onShowAdDetails}>
<div data-testid='appSelection' className={`active-process-card ${className}`} onClick={onShowAdDetails}>
<div className="active-process-card-header">
<div className="active-process-card-number">
<p>

+ 60
- 0
src/mockState.js Näytä tiedosto

@@ -994,4 +994,64 @@ export const mockState = {
},
],
},
applSelection: {
ads: [],
applicantId: 21359,
applicationChannel: "",
bitBucketLink: "",
comments: [],
cv: "",
dateOfApplication: "0001-01-01T00:00:00",
email: "jelena.d.zivkovic@gmail.com",
experience: 0,
firstName: "Jelena",
githubLink: "",
lastName: "Zivkovic",
linkedlnLink: "",
phoneNumber: "",
position: "",
selectionProcesses: [
{
selectionLevel: { id: 1, name: "HR intervju" },
status: "Odrađen",
scheduler: {
email: "dzenis.hadzifejzovic@dilig.net",
firstName: "Dzenis",
id: 17,
isEnabled: true,
lastName: "Hadzifejzovic",
position: "as",
},
comment: null,
date: "2023-01-21T01:05:00",
link: null,
},
{
selectionLevel: { id: 2, name: "Screening Test" },
status: "Odrađen",
comment: null,
date: "2023-01-21T01:05:00",
link: null,
scheduler: null
},
{
selectionLevel: { id: 3, name: "Tehnički intervju" },
status: "Odrađen",
comment: null,
date: "2023-01-21T01:05:00",
link: null,
scheduler: null
},
{
selectionLevel: { id: 4, name: "Konačna odluka" },
status: "Čeka na zakazivanje",
comment: null,
date: "2023-01-21T01:05:00",
link: null,
scheduler: null
},
],
technologyApplicants: [],
typeOfEmployment: "Intership",
},
};

+ 1
- 1
src/pages/SelectionProcessPage/SelectionProcessOfApplicantPage.js Näytä tiedosto

@@ -105,7 +105,7 @@ const SelectionProcessOfApplicantPage = () => {
<div className="l-t-rectangle"></div>
<div className="r-b-rectangle"></div>
{/* <AdFilters /> */}
<div className="ads">
<div data-testid='appl-sel' className="ads">
{processes && processes.length > 0 && (
<div className="active-ads">
<div className="active-ads-header">

+ 6
- 6
src/store/saga/loginSaga.js Näytä tiedosto

@@ -48,7 +48,7 @@ import {
} from "../../util/helpers/authScopeHelpers";
import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper";

function* fetchUser({ payload }) {
export function* fetchUser({ payload }) {
try {
const { data } = yield call(attemptLogin, payload);
if (data) {
@@ -72,7 +72,7 @@ function* fetchUser({ payload }) {
}
}

function* forgetPassword({ payload }) {
export function* forgetPassword({ payload }) {
try {
const { data } = yield call(forgetPasswordEmailSend, payload);
yield put(forgetPasswordSuccess(data));
@@ -92,7 +92,7 @@ function* forgetPassword({ payload }) {
}
}

function* resetPassword({ payload }) {
export function* resetPassword({ payload }) {
try {
const { data } = yield call(sendResetPassword, payload);
yield put(forgetPasswordSuccess(data));
@@ -110,7 +110,7 @@ function* resetPassword({ payload }) {
}
}

function* fetchGoogleUser({ payload }) {
export function* fetchGoogleUser({ payload }) {
try {
const { data } = yield call(attemptGoogleLogin, payload);
if (data.token) {
@@ -136,7 +136,7 @@ function* fetchGoogleUser({ payload }) {
}
}
}
function* authenticateUser() {
export function* authenticateUser() {
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);

@@ -158,7 +158,7 @@ function* authenticateUser() {
}
}

function* logoutUser() {
export function* logoutUser() {
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
const user = jwt.decode(JwtToken);

Loading…
Peruuta
Tallenna