-
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 #9 from atlp-rwanda/ft-reset-password-#187419121
#187419121 user should reset a password using email link
- Loading branch information
Showing
18 changed files
with
675 additions
and
19 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 |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import "@testing-library/jest-dom"; | ||
import { | ||
render, screen, fireEvent, waitFor, | ||
} from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { Provider } from "react-redux"; | ||
import { BrowserRouter as Router } from "react-router-dom"; | ||
|
||
import store from "../redux/store"; | ||
import GetLinkPage from "../pages/GetLinkPage"; | ||
import { getLink } from "../redux/reducers/getLinkSlice"; | ||
import axios from "../redux/api/api"; | ||
|
||
jest.mock("../redux/api/api"); | ||
jest.mock("react-toastify", () => ({ | ||
toast: { | ||
success: jest.fn(), | ||
error: jest.fn(), | ||
}, | ||
ToastContainer: jest.fn(), | ||
})); | ||
|
||
describe("GetLinkPage and getLinkSlice", () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
test("should render GetLinkPage correctly", () => { | ||
render( | ||
<Provider store={store}> | ||
<Router> | ||
<GetLinkPage /> | ||
</Router> | ||
</Provider>, | ||
); | ||
|
||
expect(screen.getByText("eagles", { exact: false })).toBeInTheDocument(); | ||
expect( | ||
screen.getByText("Get a link to reset password"), | ||
).toBeInTheDocument(); | ||
expect(screen.getByPlaceholderText("Email")).toBeInTheDocument(); | ||
expect(screen.getByText("Send Link")).toBeInTheDocument(); | ||
}); | ||
|
||
test("should handle initial state", () => { | ||
expect(store.getState().getLink).toEqual({ | ||
isLoading: false, | ||
data: [], | ||
error: null, | ||
}); | ||
}); | ||
|
||
test("should handle getLink.pending", () => { | ||
// @ts-ignore | ||
store.dispatch(getLink.pending()); | ||
expect(store.getState().getLink).toEqual({ | ||
isLoading: true, | ||
data: [], | ||
error: null, | ||
}); | ||
}); | ||
|
||
test("should handle getLink.fulfilled", () => { | ||
const mockData = { message: "Reset link sent successfully" }; | ||
store.dispatch( | ||
getLink.fulfilled(mockData, "", { email: "[email protected]" }), | ||
); | ||
expect(store.getState().getLink).toEqual({ | ||
isLoading: false, | ||
data: mockData, | ||
error: null, | ||
}); | ||
}); | ||
|
||
test("should handle form submission", async () => { | ||
const mockData = { message: "Reset link sent successfully" }; | ||
(axios.post as jest.Mock).mockResolvedValueOnce({ data: mockData }); | ||
|
||
render( | ||
<Provider store={store}> | ||
<Router> | ||
<GetLinkPage /> | ||
</Router> | ||
</Provider>, | ||
); | ||
|
||
const emailInput = screen.getByPlaceholderText("Email"); | ||
const submitButton = screen.getByText("Send Link"); | ||
|
||
userEvent.type(emailInput, "[email protected]"); | ||
fireEvent.click(submitButton); | ||
|
||
await waitFor(() => { | ||
expect(store.getState().getLink.isLoading).toBe(false); | ||
expect(store.getState().getLink.data).toEqual(mockData); | ||
}); | ||
}); | ||
|
||
test("should show success message after successful submission", async () => { | ||
const mockData = { message: "Reset link sent successfully" }; | ||
(axios.post as jest.Mock).mockResolvedValueOnce({ data: mockData }); | ||
|
||
render( | ||
<Provider store={store}> | ||
<Router> | ||
<GetLinkPage /> | ||
</Router> | ||
</Provider>, | ||
); | ||
|
||
const emailInput = screen.getByPlaceholderText("Email"); | ||
const submitButton = screen.getByText("Send Link"); | ||
|
||
userEvent.type(emailInput, "[email protected]"); | ||
fireEvent.click(submitButton); | ||
|
||
await waitFor(() => { | ||
expect(store.getState().getLink.data).toEqual(mockData); | ||
}); | ||
}); | ||
|
||
test("getLink thunk should make API call and handle success", async () => { | ||
const mockData = { message: "Reset link sent successfully" }; | ||
(axios.post as jest.Mock).mockResolvedValueOnce({ data: mockData }); | ||
|
||
const dispatch = jest.fn(); | ||
const thunk = getLink({ email: "[email protected]" }); | ||
|
||
await thunk(dispatch, () => ({}), undefined); | ||
|
||
const { calls } = dispatch.mock; | ||
expect(calls[0][0].type).toBe("getLinkEmail/pending"); | ||
expect(calls[1][0].type).toBe("getLinkEmail/fulfilled"); | ||
expect(calls[1][0].payload).toEqual(mockData); | ||
}); | ||
}); |
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,85 @@ | ||
// @ts-nocheck | ||
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 { AnyAction } from "@reduxjs/toolkit"; | ||
|
||
import store from "../redux/store"; | ||
import ResetPassword from "../pages/ResetPassword"; | ||
import { resetPassword } from "../redux/reducers/resetPasswordSlice"; | ||
|
||
test("should render reset password page correctly", async () => { | ||
render( | ||
<Provider store={store}> | ||
<Router> | ||
<ResetPassword /> | ||
</Router> | ||
</Provider>, | ||
); | ||
|
||
expect(screen.getByText("eagles", { exact: false })).toBeInTheDocument(); | ||
expect( | ||
screen.getByText("Reset your password", { exact: false }), | ||
).toBeInTheDocument(); | ||
const description = screen.getAllByText( | ||
"Before you write your password consider if your password is strong enough that can not be guessed or cracked by anyone.", | ||
); | ||
const newPassword = screen.getAllByPlaceholderText("New Password"); | ||
const confirmPassword = screen.getAllByPlaceholderText("Confirm password"); | ||
|
||
expect(description).toBeTruthy(); | ||
expect(newPassword).toBeTruthy(); | ||
expect(confirmPassword).toBeTruthy(); | ||
}); | ||
|
||
test("the link is not disabled", () => { | ||
const { getByText } = render( | ||
<Provider store={store}> | ||
<Router> | ||
<ResetPassword /> | ||
</Router> | ||
</Provider>, | ||
); | ||
const linkElement = getByText("Reset"); | ||
expect(linkElement).not.toBeDisabled(); | ||
expect(linkElement).toBeEnabled(); | ||
expect(linkElement).toBeVisible(); | ||
}); | ||
|
||
it("should handle initial state", () => { | ||
expect(store.getState().reset).toEqual({ | ||
isLoading: false, | ||
data: [], | ||
error: null, | ||
}); | ||
}); | ||
|
||
it("should handle resetPassword.pending", () => { | ||
// @ts-ignore | ||
store.dispatch(resetPassword.pending("")); | ||
expect(store.getState().reset).toEqual({ | ||
isLoading: true, | ||
data: [], | ||
error: null, | ||
}); | ||
}); | ||
|
||
it("should handle resetPassword.fulfilled", () => { | ||
const mockData = { message: "Password reset successfully" }; | ||
store.dispatch(resetPassword.fulfilled(mockData, "", {} as AnyAction)); | ||
expect(store.getState().reset).toEqual({ | ||
isLoading: false, | ||
data: mockData, | ||
error: null, | ||
}); | ||
}); | ||
|
||
it("should handle resetPassword.rejected", () => { | ||
store.dispatch(resetPassword.rejected(null, "", {} as AnyAction)); | ||
expect(store.getState().reset).toEqual({ | ||
isLoading: false, | ||
data: [], | ||
error: undefined, | ||
}); | ||
}); |
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,12 @@ | ||
import { FaCircle } from "react-icons/fa"; | ||
|
||
const Logo = () => ( | ||
<div className="text-black font-bold text-[30px] flex items-center gap-1 p-5"> | ||
<h1 className="font-medium text-[36px]"> | ||
<span className="font-[550] text-heading"> eagles</span> | ||
</h1> | ||
<FaCircle className="text-sm text-[#DB4444] mt-3" /> | ||
</div> | ||
); | ||
|
||
export default Logo; |
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,10 @@ | ||
import { createSlice } from "@reduxjs/toolkit"; | ||
// @ts-ignore | ||
const createCustomSlice = (name, initialState, extraReducers) => createSlice({ | ||
name, | ||
initialState, | ||
reducers: {}, | ||
extraReducers, | ||
}); | ||
|
||
export default createCustomSlice; |
Oops, something went wrong.