-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
510ebe8
commit 78bfdc6
Showing
16 changed files
with
198 additions
and
26 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 |
---|---|---|
@@ -1,22 +1,60 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { User } from "firebase/auth"; | ||
import { MemoryRouter } from "react-router-dom"; | ||
|
||
import { UserContext } from "@/contexts/userContext"; | ||
import { signOutUser } from "@/utils/firebase"; | ||
import NavigationBar from "./NavigationBar"; | ||
|
||
const currentUser = { displayName: "Alice" } as User; | ||
const setCurrentUser = vi.fn(); | ||
|
||
function setup(currentUser: User | null) { | ||
const value = { currentUser, setCurrentUser }; | ||
|
||
render( | ||
<UserContext.Provider value={value}> | ||
<NavigationBar /> | ||
</UserContext.Provider>, | ||
{ wrapper: MemoryRouter }, | ||
); | ||
|
||
return userEvent.setup(); | ||
} | ||
|
||
vi.mock("firebase/auth"); | ||
vi.mock("@/utils/firebase"); | ||
|
||
test("should render a logo", function () { | ||
render(<NavigationBar />, { wrapper: MemoryRouter }); | ||
setup(currentUser); | ||
const logoElement = screen.getByTestId("crown-logo"); | ||
expect(logoElement).toBeInTheDocument(); | ||
}); | ||
|
||
test("should have a link to the shop page", function () { | ||
render(<NavigationBar />, { wrapper: MemoryRouter }); | ||
setup(currentUser); | ||
const shopLinkElement = screen.getByText(/shop/i); | ||
expect(shopLinkElement).toHaveAttribute("href", "/shop"); | ||
}); | ||
|
||
test("should have a link to the authentication page", function () { | ||
render(<NavigationBar />, { wrapper: MemoryRouter }); | ||
setup(null); | ||
const signInLinkElement = screen.getByText(/sign in/i); | ||
expect(signInLinkElement).toHaveAttribute("href", "/auth"); | ||
}); | ||
|
||
test("should show the sign out link when a user is signed in", function () { | ||
setup(currentUser); | ||
const signOutLinkElement = screen.getByText(/sign out/i); | ||
expect(signOutLinkElement).toBeInTheDocument(); | ||
}); | ||
|
||
test("should call the sign out function when the sign out link is clicked", async function () { | ||
const { click } = setup(currentUser); | ||
const signOutLinkElement = screen.getByText(/sign out/i); | ||
await click(signOutLinkElement); | ||
|
||
expect(signOutUser).toHaveBeenCalled(); | ||
expect(setCurrentUser).toHaveBeenCalledWith(null); | ||
}); |
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
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 |
---|---|---|
@@ -1,5 +1,8 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { User } from "firebase/auth"; | ||
|
||
import { UserContext } from "@/contexts/userContext"; | ||
|
||
import SignInForm from "./SignInForm"; | ||
|
||
|
@@ -31,6 +34,22 @@ vi.mock("@/utils/firebase", async function () { | |
|
||
vi.spyOn(window, "alert").mockImplementation(() => {}); | ||
|
||
const authUser = { displayName: "Alice" } as User; | ||
const setCurrentUser = vi.fn(); | ||
|
||
function setup() { | ||
const user = userEvent.setup(); | ||
const ctx = { currentUser: null, setCurrentUser }; | ||
|
||
render( | ||
<UserContext.Provider value={ctx}> | ||
<SignInForm /> | ||
</UserContext.Provider>, | ||
); | ||
|
||
return user; | ||
} | ||
|
||
beforeEach(() => { | ||
vi.clearAllMocks(); | ||
}); | ||
|
@@ -61,22 +80,24 @@ test("should render the correct buttons", function () { | |
}); | ||
|
||
test("should submit the form with the correct data", async function () { | ||
render(<SignInForm />); | ||
mocks.signInAuthUserFn.mockResolvedValueOnce({ user: authUser }); | ||
const { type, click } = setup(); | ||
|
||
const emailInput = screen.getByLabelText(/email/i); | ||
const passwordInput = screen.getByLabelText(/password/i); | ||
const submitButton = screen.getByRole("button", { name: /^sign in$/i }); | ||
|
||
const user = userEvent.setup(); | ||
|
||
await user.type(emailInput, "[email protected]"); | ||
await user.type(passwordInput, "password"); | ||
await user.click(submitButton); | ||
await type(emailInput, "[email protected]"); | ||
await type(passwordInput, "password"); | ||
await click(submitButton); | ||
|
||
expect(mocks.signInAuthUserFn).toHaveBeenCalledWith( | ||
"[email protected]", | ||
"password", | ||
); | ||
|
||
expect(setCurrentUser).toHaveBeenCalledOnce(); | ||
expect(setCurrentUser).toHaveBeenCalledWith(authUser); | ||
}); | ||
|
||
test("should show an alert if the password is incorrect", async function () { | ||
|
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 |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import userEvent from "@testing-library/user-event"; | ||
|
||
import { UserContext } from "@/contexts/userContext"; | ||
|
||
import SignUpForm from "./SignUpForm"; | ||
|
||
const mockedMethods = vi.hoisted(function () { | ||
|
@@ -23,6 +25,21 @@ mockedMethods.createAuthUserFn.mockResolvedValue({ | |
|
||
vi.spyOn(window, "alert").mockImplementation(() => {}); | ||
|
||
const setCurrentUser = vi.fn(); | ||
|
||
function setup() { | ||
const user = userEvent.setup(); | ||
const ctx = { currentUser: null, setCurrentUser }; | ||
|
||
render( | ||
<UserContext.Provider value={ctx}> | ||
<SignUpForm /> | ||
</UserContext.Provider>, | ||
); | ||
|
||
return user; | ||
} | ||
|
||
beforeEach(function () { | ||
vi.clearAllMocks(); | ||
}); | ||
|
@@ -52,21 +69,19 @@ test("should render the correct buttons", function () { | |
}); | ||
|
||
test("should submit the form with the correct data", async function () { | ||
render(<SignUpForm />); | ||
const { type, click } = setup(); | ||
|
||
const displayNameInput = screen.getByLabelText(/display name/i); | ||
const emailInput = screen.getByLabelText(/email/i); | ||
const passwordInput = screen.getByLabelText(/^password/i); | ||
const confirmPasswordInput = screen.getByLabelText(/^confirm password/i); | ||
const submitButton = screen.getByRole("button", { name: /sign up/i }); | ||
|
||
const user = userEvent.setup(); | ||
|
||
await user.type(displayNameInput, "John Doe"); | ||
await user.type(emailInput, "[email protected]"); | ||
await user.type(passwordInput, "password"); | ||
await user.type(confirmPasswordInput, "password"); | ||
await user.click(submitButton); | ||
await type(displayNameInput, "John Doe"); | ||
await type(emailInput, "[email protected]"); | ||
await type(passwordInput, "password"); | ||
await type(confirmPasswordInput, "password"); | ||
await click(submitButton); | ||
|
||
expect(mockedMethods.createAuthUserFn).toHaveBeenCalledWith( | ||
"[email protected]", | ||
|
@@ -77,6 +92,9 @@ test("should submit the form with the correct data", async function () { | |
{ uid: "123" }, | ||
{ displayName: "John Doe" }, | ||
); | ||
|
||
expect(setCurrentUser).toHaveBeenCalledOnce(); | ||
expect(setCurrentUser).toHaveBeenCalledWith({ uid: "123" }); | ||
}); | ||
|
||
test("should show an alert if passwords do not match", async function () { | ||
|
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,28 @@ | ||
import { render } from "@testing-library/react"; | ||
import { useContext, useEffect } from "react"; | ||
|
||
import { User } from "firebase/auth"; | ||
import UserContextProvider, { UserContext } from "./userContext"; | ||
|
||
function setup() { | ||
function Consumer() { | ||
const { currentUser, setCurrentUser } = useContext(UserContext); | ||
|
||
useEffect(() => { | ||
setCurrentUser({ displayName: "Alice" } as User); | ||
}, [setCurrentUser]); | ||
|
||
return <div>{currentUser?.displayName}</div>; | ||
} | ||
|
||
render( | ||
<UserContextProvider> | ||
<Consumer /> | ||
</UserContextProvider>, | ||
); | ||
} | ||
|
||
test("should provide the correct context values", () => { | ||
setup(); | ||
expect(document.body.textContent).toBe("Alice"); | ||
}); |
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,24 @@ | ||
import { User } from "firebase/auth"; | ||
import { createContext, Dispatch, SetStateAction, useState } from "react"; | ||
|
||
interface IUserContext { | ||
currentUser: User | null; | ||
setCurrentUser: Dispatch<SetStateAction<User | null>>; | ||
} | ||
|
||
// eslint-disable-next-line react-refresh/only-export-components | ||
export const UserContext = createContext<IUserContext>({ | ||
currentUser: null, | ||
setCurrentUser: () => {}, | ||
}); | ||
|
||
export default function UserContextProvider({ | ||
children, | ||
}: { | ||
children: React.ReactNode; | ||
}) { | ||
const [currentUser, setCurrentUser] = useState<User | null>(null); | ||
const value = { currentUser, setCurrentUser }; | ||
|
||
return <UserContext.Provider value={value}>{children}</UserContext.Provider>; | ||
} |
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 |
---|---|---|
@@ -1,13 +1,17 @@ | ||
import { StrictMode } from "react"; | ||
import { createRoot } from "react-dom/client"; | ||
|
||
import UserContextProvider from "@/contexts/userContext.tsx"; | ||
|
||
import App from "./App.tsx"; | ||
import "./index.css"; | ||
|
||
const rootEl = document.getElementById("root"); | ||
|
||
createRoot(rootEl!).render( | ||
<StrictMode> | ||
<App /> | ||
<UserContextProvider> | ||
<App /> | ||
</UserContextProvider> | ||
</StrictMode>, | ||
); |
Oops, something went wrong.