-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from atlp-rwanda/ft-seller-auth-2f-#187419122
#187419122 Seller Authentication and Two factor authentication for seller
- Loading branch information
Showing
25 changed files
with
1,350 additions
and
1,009 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,3 +38,6 @@ jobs: | |
uses: codecov/[email protected] | ||
with: | ||
token: ${{ secrets.CODECOV_TOKEN }} | ||
- name: Coveralls GitHub Action | ||
uses: coverallsapp/[email protected] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,3 +27,4 @@ dist-ssr | |
|
||
# Environment variables | ||
.env | ||
coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { verifyOtp, otpVerificationApiSlice } from "../redux/api/otpApiSclice"; | ||
|
||
const { reducer } = otpVerificationApiSlice; | ||
describe("otpVerification slice", () => { | ||
it("handles pending state on verifyOtp.pending", () => { | ||
// @ts-ignore | ||
const initialState = reducer(undefined, { type: verifyOtp.pending }); | ||
expect(initialState.loading).toBeTruthy(); | ||
}); | ||
|
||
it("handles fulfilled state and data on verifyOtp.fulfilled", () => { | ||
const mockData = { message: "Success" }; | ||
const initialState = reducer(undefined, { | ||
// @ts-ignore | ||
type: verifyOtp.fulfilled, | ||
payload: mockData, | ||
}); | ||
expect(initialState.success).toBeTruthy(); | ||
}); | ||
|
||
it("handles rejected state and error on verifyOtp.rejected", () => { | ||
const error = { message: "Error" }; | ||
const initialState = reducer(undefined, { | ||
// @ts-ignore | ||
type: verifyOtp.rejected, | ||
payload: error, | ||
}); | ||
expect(initialState.error).toBe("Error"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
import "@testing-library/jest-dom"; | ||
import { | ||
render, screen, fireEvent, waitFor, | ||
} from "@testing-library/react"; | ||
import { Provider } from "react-redux"; | ||
import { BrowserRouter } from "react-router-dom"; | ||
import configureStore from "redux-mock-store"; | ||
import { thunk } from "redux-thunk"; | ||
import { toast } from "react-toastify"; | ||
|
||
import OtpVerificationForm from "../pages/otpVerfication"; | ||
|
||
jest.mock("react-toastify", () => ({ | ||
toast: { | ||
// @ts-ignore | ||
success: jest.fn(), | ||
error: jest.fn(), | ||
}, | ||
ToastContainer: () => <div />, | ||
})); | ||
|
||
jest.mock("../redux/api/otpApiSclice", () => ({ | ||
verifyOtp: jest.fn(), | ||
})); | ||
|
||
const middlewares = [thunk]; | ||
// @ts-ignores | ||
const mockStore = configureStore(middlewares); | ||
// @ts-ignore | ||
const renderComponent = (store) => render( | ||
<Provider store={store}> | ||
<BrowserRouter> | ||
<OtpVerificationForm /> | ||
</BrowserRouter> | ||
</Provider>, | ||
); | ||
|
||
describe("OtpVerification", () => { | ||
// @ts-ignore | ||
let store; | ||
beforeEach(() => { | ||
store = mockStore({ | ||
otpVerification: { | ||
loading: false, | ||
}, | ||
}); | ||
localStorage.clear(); | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it("renders correctly", () => { | ||
renderComponent(store); | ||
expect(screen.getByText("verify your identity")).toBeInTheDocument(); | ||
expect( | ||
screen.getByText( | ||
"Protecting your account is our priority. Please confirm your identity by providing the code sent to your email address", | ||
), | ||
).toBeInTheDocument(); | ||
}); | ||
it("navigates to login on cancel", () => { | ||
renderComponent(store); | ||
fireEvent.click(screen.getByText("Cancel")); | ||
expect(window.location.pathname).toBe("/login"); | ||
}); | ||
|
||
it("focuses on the next input on entering a digit", () => { | ||
renderComponent(store); | ||
const inputs = screen.getAllByRole("textbox"); | ||
inputs.forEach((input, index) => { | ||
fireEvent.change(input, { target: { value: "1" } }); | ||
if (index < inputs.length - 1) { | ||
expect(document.activeElement).toBe(inputs[index + 1]); | ||
} | ||
}); | ||
}); | ||
it("handles paste event", () => { | ||
renderComponent(store); | ||
const inputs = screen.getAllByRole("textbox"); | ||
fireEvent.paste(inputs[0], { | ||
clipboardData: { | ||
getData: () => "123456", | ||
}, | ||
}); | ||
inputs.forEach((input, index) => { | ||
// @ts-ignore | ||
expect(input.value).toBe(String(index + 1)); | ||
}); | ||
}); | ||
|
||
it("handles backspace correctly", () => { | ||
renderComponent(store); | ||
const inputs = screen.getAllByRole("textbox"); | ||
inputs.forEach((input, index) => { | ||
fireEvent.change(input, { target: { value: String(index + 1) } }); | ||
}); | ||
fireEvent.keyDown(inputs[5], { key: "Backspace", code: "Backspace" }); | ||
expect(document.activeElement).toBe(inputs[5]); | ||
}); | ||
|
||
it("should handle submit with success", async () => { | ||
const { getByText } = renderComponent(store); | ||
const form = getByText("Ver"); | ||
fireEvent.submit(form); | ||
expect(toast.success).toHaveBeenCalledTimes(0); | ||
}); | ||
|
||
it("should handle submit with error", async () => { | ||
const { getByText } = renderComponent(store); | ||
const form = getByText("Ver"); | ||
fireEvent.submit(form); | ||
await waitFor(() => expect(toast.error).toHaveBeenCalledTimes(0)); | ||
}); | ||
|
||
it("should handle backspace key press", () => { | ||
const { getAllByRole } = renderComponent(store); | ||
const inputs = getAllByRole("textbox"); | ||
fireEvent.keyDown(inputs[0], { key: "Backspace" }); | ||
// @ts-ignore | ||
expect(inputs[0].value).toBe(""); | ||
}); | ||
|
||
it("should handle paste with same length", () => { | ||
const { getAllByRole } = renderComponent(store); | ||
const inputs = getAllByRole("textbox"); | ||
const pasteValue = "123456"; | ||
fireEvent.paste(inputs[0], { | ||
clipboardData: { getData: () => pasteValue }, | ||
}); | ||
// @ts-ignore | ||
inputs.forEach((input, index) => expect(input.value).toBe(pasteValue[index])); | ||
}); | ||
it("should handle paste with shorter length", () => { | ||
const { getAllByRole } = renderComponent(store); | ||
const inputs = getAllByRole("textbox"); | ||
const pasteValue = "123"; | ||
fireEvent.paste(inputs[0], { | ||
clipboardData: { getData: () => pasteValue }, | ||
}); | ||
inputs.forEach((input, index) => { | ||
if (index < pasteValue.length) { | ||
// @ts-ignore | ||
expect(input.value).toBe(pasteValue[index]); | ||
} else { | ||
// @ts-ignore | ||
expect(input.value).toBe(""); | ||
} | ||
}); | ||
}); | ||
|
||
it("should render form elements", () => { | ||
const { getByText } = renderComponent(store); | ||
|
||
expect( | ||
getByText( | ||
"Protecting your account is our priority. Please confirm your identity by providing the code sent to your email address", | ||
), | ||
).toBeInTheDocument(); | ||
expect(getByText("Cancel")).toBeInTheDocument(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import "@testing-library/jest-dom"; | ||
import { render, screen } from "@testing-library/react"; | ||
import { Provider } from "react-redux"; | ||
import { BrowserRouter as Router } from "react-router-dom"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { ToastContainer } from "react-toastify"; | ||
|
||
import UpdatePasswordmod from "../components/password/UpdateModal"; | ||
import store from "../redux/store"; | ||
|
||
test("test update password", () => { | ||
const setPasswordModal = jest.fn(); | ||
render( | ||
<Provider store={store}> | ||
<Router> | ||
<UpdatePasswordmod setPasswordModal={setPasswordModal} /> | ||
<ToastContainer /> | ||
</Router> | ||
</Provider>, | ||
); | ||
|
||
const currentPasswordInput = screen.getByPlaceholderText("Old Password"); | ||
const newPasswordInput = screen.getByPlaceholderText("New Password"); | ||
const confirmNewPasswordInput = screen.getByPlaceholderText("Confirm Password"); | ||
const updateButton = screen.getByRole("button", { name: /Save Changes/i }); | ||
|
||
userEvent.type(currentPasswordInput, "Test@123"); | ||
userEvent.type(newPasswordInput, "NewTest@123"); | ||
userEvent.type(confirmNewPasswordInput, "NewTest@123"); | ||
|
||
userEvent.click(updateButton); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import React, { useState } from "react"; | ||
import { FieldError, UseFormRegisterReturn } from "react-hook-form"; | ||
|
||
interface PasswordInputProps { | ||
id: string; | ||
placeholder: string; | ||
register: UseFormRegisterReturn; | ||
error: FieldError | undefined; | ||
} | ||
|
||
const PasswordInput: React.FC<PasswordInputProps> = ({ | ||
id, | ||
placeholder, | ||
register, | ||
error, | ||
}) => { | ||
const [showPassword, setShowPassword] = useState(false); | ||
|
||
return ( | ||
<div className="mb-4 relative"> | ||
<input | ||
type={showPassword ? "text" : "password"} | ||
id={id} | ||
className={`w-full p-2 border-b ${error ? "border-red-500" : "border-gray-300"}`} | ||
placeholder={placeholder} | ||
{...register} | ||
/> | ||
<button | ||
type="button" | ||
onClick={() => setShowPassword(!showPassword)} | ||
className="absolute right-2 top-1/2 transform -translate-y-1/2" | ||
> | ||
{showPassword ? "Hide Password" : "Show Password"} | ||
</button> | ||
{error && <p className="text-red-500">{error.message}</p>} | ||
</div> | ||
); | ||
}; | ||
|
||
export default PasswordInput; |
Oops, something went wrong.