Heroes App uses a carefully assembled testing stack built on Jest 29 and React Testing Library 16 to cover reducers, routing logic, protected routes, and UI components. All test files live under aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ludwiigdev/Heroes_App/llms.txt
Use this file to discover all available pages before exploring further.
tests/ directory that mirrors the src/ folder structure, making it easy to locate tests for any module. The sections below explain every layer of the setup — from the packages that power the suite to the recurring patterns you’ll see throughout the codebase.
Testing Stack
Jest 29
The test runner and assertion framework. Configured via
jest.config.cjs to use the jsdom environment so DOM APIs are available in every test.React Testing Library 16
Renders components into the virtual DOM and exposes semantic queries (
getByRole, getByText, getByLabelText) that reflect real user interactions.@testing-library/jest-dom
Extends Jest’s
expect with DOM-specific matchers such as toBeInTheDocument, toHaveStyle, and toHaveValue.babel-jest + Babel presets
babel-jest transpiles JSX and ES Modules for Jest. @babel/preset-env targets esmodules: true and @babel/preset-react is set to the automatic runtime.jest-environment-jsdom
Provides a simulated browser environment (DOM,
localStorage, window) so components that interact with browser APIs can be tested without a real browser.identity-obj-proxy
A project dependency that can intercept CSS Module imports and return class name strings as-is. It is installed but not configured in
jest.config.cjs in the current setup.Configuration files
testEnvironment is declared twice in jest.config.cjs; the second value ("jsdom") is the effective one. identity-obj-proxy is listed as a project dependency but is not configured in jest.config.cjs — no moduleNameMapper key is present in the current config.Directory Structure
Thetests/ tree mirrors src/ so every test file sits at the same relative depth as the module it covers.
Test File Responsibilities
tests/auth/context/authReducer.test.js
tests/auth/context/authReducer.test.js
Tests the
authReducer pure function in isolation. Verifies that:- Dispatching an unknown action returns the current state unchanged.
- A
types.loginaction setslogged: trueand attaches the user payload. - A
types.logoutaction resets the state to{ logged: false }, removing the user.
authReducer is a plain function with no side effects, no DOM or router setup is needed — the tests are purely input/output assertions.The logout assertions are written outside the
describe block in the actual test file — a quirk of the source. The logout test() body is empty; the real assertions run at module scope rather than inside a test case.tests/auth/types/types.test.js
tests/auth/types/types.test.js
A simple equality check that guards against accidental string changes in the action-type constants. It asserts that
types exports exactly { login: "[Auth] Login", logout: "[Auth] Logout" }. Any rename will immediately fail this test and signal that dependent reducers and dispatches need to be updated.tests/router/AppRouter.test.jsx
tests/router/AppRouter.test.jsx
Tests the top-level
AppRouter component by wrapping it in both MemoryRouter and a mocked AuthContext.Provider. Two scenarios are covered:- Unauthenticated (
logged: false): navigating to/marvelrenders the Login page instead. - Authenticated (
logged: true): navigating to/loginredirects to the Marvel listing.
tests/router/PrivateRoute.test.jsx
tests/router/PrivateRoute.test.jsx
Renders
PrivateRoute with an authenticated context and confirms that its children are displayed. Also spies on localStorage.setItem to verify that PrivateRoute persists the current path as "lastPath" — enabling post-login redirect to the last visited URL.tests/router/PublicRoute.test.jsx
tests/router/PublicRoute.test.jsx
Two scenarios mirror
PrivateRoute:- Unauthenticated:
childrenare rendered normally. - Authenticated: the component redirects away from
/loginto/marvel, so the public child is never shown.
tests/Heroes/pages/SearchPage.test.jsx
tests/Heroes/pages/SearchPage.test.jsx
Covers three scenarios for
SearchPage:- Snapshot: default render with no query string matches the stored snapshot.
- Query string hydration:
?q=batmanpre-fills the text input and asserts the error alert is hidden (display: "none"). - No match:
?q=batman123shows the error alert (display: "").
useNavigate is mocked at the module level to prevent real navigation during tests.tests/ui/components/Navbar.test.jsx
tests/ui/components/Navbar.test.jsx
Testing Patterns
The project relies on five recurring patterns. Understanding them makes it straightforward to add new tests that are consistent with the existing suite.1 — MemoryRouter with initialEntries
Any component that uses React Router hooks or renders <Link> / <Navigate> must be wrapped in a router. MemoryRouter is used instead of BrowserRouter because it accepts an initialEntries array to simulate a specific URL without touching the browser’s address bar.
2 — Mocking AuthContext via AuthContext.Provider
Components that consume useContext(AuthContext) receive the context value from the nearest <AuthContext.Provider>. Tests inject a plain object as the value, controlling exactly which shape of auth state the component sees.
3 — Mocking useNavigate
useNavigate returns a function that imperatively pushes to the history stack. In tests, this side effect is replaced with a jest.fn() at the module level so navigation calls can be asserted without actually changing routes.
4 — Snapshot Testing
SearchPage includes a snapshot test that serialises the rendered DOM on first run and saves it to __snapshots__/SearchPage.test.jsx.snap. Subsequent runs diff against that snapshot, catching unintentional UI regressions.
5 — Pure Reducer Testing
authReducer is a plain JavaScript function, so its tests require no DOM setup — just import, call, and assert. This pattern is the fastest and most reliable kind of test because there are no asynchronous operations, no rendering, and no mocks.
