test(web): increase frontend test coverage to ~70% page coverage
- Fix vitest config to include [locale] directory tests (was excluded)
- Fix register.spec.tsx: use getByRole('heading') to avoid duplicate text match
- Fix search.spec.tsx: add QueryClientProvider wrapper and mock saved searches hook
- Add 12 new page test files covering dashboard, admin, public, and OAuth pages:
- dashboard (main, profile, payments, subscription, KYC)
- admin (dashboard, users)
- public (landing, pricing)
- analytics
- OAuth callbacks (Google, Zalo)
- 29 test files, 174 tests, 16/23 pages covered (69.6%)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -106,9 +106,28 @@ vi.mock('@/lib/listings-api', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/lib/hooks/use-saved-searches', () => ({
|
||||
useCreateSavedSearch: () => ({
|
||||
mutateAsync: vi.fn(),
|
||||
isPending: false,
|
||||
}),
|
||||
useSavedSearches: () => ({ data: [], isLoading: false }),
|
||||
}));
|
||||
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { listingsApi } from '@/lib/listings-api';
|
||||
import SearchPage from '../page';
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
});
|
||||
|
||||
function Wrapper({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
const mockedListingsApi = vi.mocked(listingsApi);
|
||||
|
||||
describe('SearchPage', () => {
|
||||
@@ -118,7 +137,7 @@ describe('SearchPage', () => {
|
||||
});
|
||||
|
||||
it('renders the search page title', async () => {
|
||||
render(<SearchPage />);
|
||||
render(<SearchPage />, { wrapper: Wrapper });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Tìm kiếm bất động sản')).toBeInTheDocument();
|
||||
@@ -126,7 +145,7 @@ describe('SearchPage', () => {
|
||||
});
|
||||
|
||||
it('renders view mode toggle buttons', async () => {
|
||||
render(<SearchPage />);
|
||||
render(<SearchPage />, { wrapper: Wrapper });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('button', { name: /danh sách/i })).toBeInTheDocument();
|
||||
@@ -135,7 +154,7 @@ describe('SearchPage', () => {
|
||||
});
|
||||
|
||||
it('calls listings API on mount', async () => {
|
||||
render(<SearchPage />);
|
||||
render(<SearchPage />, { wrapper: Wrapper });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockedListingsApi.search).toHaveBeenCalled();
|
||||
@@ -143,7 +162,7 @@ describe('SearchPage', () => {
|
||||
});
|
||||
|
||||
it('displays listing results after loading', async () => {
|
||||
render(<SearchPage />);
|
||||
render(<SearchPage />, { wrapper: Wrapper });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/căn hộ quận 7/i)).toBeInTheDocument();
|
||||
@@ -151,7 +170,7 @@ describe('SearchPage', () => {
|
||||
});
|
||||
|
||||
it('switches to map view when map button is clicked', async () => {
|
||||
render(<SearchPage />);
|
||||
render(<SearchPage />, { wrapper: Wrapper });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('button', { name: /bản đồ/i })).toBeInTheDocument();
|
||||
|
||||
Reference in New Issue
Block a user