Portal Testing¶
The borrower portal uses Vitest with Testing Library for component testing.
Setup¶
Tests run in a jsdom environment via Vitest.
Test Utilities¶
test-utils.tsx provides a renderWithProviders() helper that wraps components in all required providers.
renderWithProviders(ui, options?)¶
import { renderWithProviders } from "@/test-utils";
test("renders dashboard", () => {
renderWithProviders(<DashboardPage />);
});
Default providers applied:
- QueryClientProvider:
createTestQueryClient()withretry: false - MemoryRouter: React Router for route-dependent components
- ThemeProvider: MUI theme
- AuthContext: Authenticated with a default borrower
Default Test Borrower¶
const defaultBorrower: BorrowerProfile = {
id: "test-id",
first_name: "Jane",
last_name: "Doe",
email: "jane@example.com",
phone: "+12125551234",
date_of_birth: "1990-01-15",
ssn_last_four: "1234",
language_preference: "en",
communication_preference: "email",
};
Overriding Auth State¶
Pass custom auth state for testing unauthenticated or different user scenarios:
renderWithProviders(<LoginPage />, {
auth: {
borrower: null,
isAuthenticated: false,
isLoading: false,
login: vi.fn(),
logout: vi.fn(),
},
});
Custom Routes¶
For testing route-dependent components:
Writing Tests¶
Page Component Tests¶
import { screen } from "@testing-library/react";
import { renderWithProviders } from "@/test-utils";
import DashboardPage from "@/pages/DashboardPage";
test("shows welcome message", () => {
renderWithProviders(<DashboardPage />);
expect(screen.getByText(/Welcome, Jane/)).toBeInTheDocument();
});
Component Tests¶
import { screen } from "@testing-library/react";
import { renderWithProviders } from "@/test-utils";
import MoneyDisplay from "@/components/MoneyDisplay";
test("formats currency", () => {
renderWithProviders(
<MoneyDisplay value={{ amount: "1234.56", currency: "USD" }} />,
);
expect(screen.getByText("$1,234.56")).toBeInTheDocument();
});
Testing User Interactions¶
import { screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { renderWithProviders } from "@/test-utils";
test("submits login form", async () => {
const mockLogin = vi.fn();
renderWithProviders(<LoginPage />, {
auth: { ...defaultAuth, login: mockLogin, isAuthenticated: false, borrower: null },
});
await userEvent.type(screen.getByLabelText(/email/i), "test@example.com");
await userEvent.type(screen.getByLabelText(/password/i), "password123");
await userEvent.click(screen.getByRole("button", { name: /sign in/i }));
await waitFor(() => {
expect(mockLogin).toHaveBeenCalledWith("test@example.com", "password123");
});
});
Test Organization¶
frontend/borrower/src/
├── pages/__tests__/ # Page component tests
├── components/__tests__/ # Shared component tests
└── hooks/__tests__/ # Hook tests (if any)
See Also¶
- Components --- Components under test
- Pages & Routing --- Page components under test