Files
goodgo-platform/apps/web/components/comparison/__tests__/compare-floating-bar.spec.tsx
Ho Ngoc Hai 154aed5440 fix: resolve all ESLint errors and TypeScript compilation errors
- Auto-fixed 712 import ordering errors via `pnpm lint --fix`
- Manually fixed 13 remaining ESLint errors:
  - Prefixed unused vars with _ (mockAdminUser, params)
  - Removed unused imports (UnauthorizedException, vi, screen)
  - Moved imports above vi.mock() calls to fix import group ordering
  - Removed eslint-disable for non-existent rules
  - Fixed empty object pattern in Playwright fixture
- Fixed ~40 TypeScript TS4111 index signature errors in test files:
  - Used bracket notation for Record<string, unknown> property access
  - Added missing PropertyMedia fields (id, order, caption) to test data
- Fixed pre-existing test failures in rate-limit guard specs:
  - Added NODE_ENV override to bypass test-mode skip in guard

Both `pnpm lint` and `pnpm typecheck` now exit 0 cleanly.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-11 23:12:08 +07:00

100 lines
3.4 KiB
TypeScript

import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, expect, it, vi, beforeEach } from 'vitest';
import { CompareFloatingBar } from '../compare-floating-bar';
// Mock next-intl
vi.mock('next-intl', () => ({
useTranslations: () => (key: string, params?: Record<string, unknown>) => {
const translations: Record<string, string> = {
selected: `${params?.['count'] ?? 0} of ${params?.['max'] ?? 5} selected`,
removeItem: 'Remove item',
clearAll: 'Clear all',
compareNow: 'Compare now',
needMore: 'Need more',
};
return translations[key] ?? key;
},
}));
// Mock i18n navigation
vi.mock('@/i18n/navigation', () => ({
Link: ({ children, href }: { children: React.ReactNode; href: string }) => (
<a href={href}>{children}</a>
),
}));
const mockStoreState = {
selectedIds: [] as string[],
clearAll: vi.fn(),
removeFromCompare: vi.fn(),
canCompare: () => false,
};
// Mock comparison store
vi.mock('@/lib/comparison-store', () => ({
useComparisonStore: (selector: (state: unknown) => unknown) => selector(mockStoreState),
MAX_COMPARE: 5,
}));
describe('CompareFloatingBar', () => {
beforeEach(() => {
vi.clearAllMocks();
mockStoreState.selectedIds = [];
mockStoreState.canCompare = () => false;
});
it('renders nothing when no items selected', () => {
const { container } = render(<CompareFloatingBar />);
expect(container.firstChild).toBeNull();
});
it('renders floating bar when items are selected', () => {
mockStoreState.selectedIds = ['listing-1'];
render(<CompareFloatingBar />);
expect(screen.getByText('1 of 5 selected')).toBeInTheDocument();
});
it('renders clear all button', () => {
mockStoreState.selectedIds = ['listing-1'];
render(<CompareFloatingBar />);
expect(screen.getByRole('button', { name: 'Clear all' })).toBeInTheDocument();
});
it('calls clearAll when clear button is clicked', async () => {
mockStoreState.selectedIds = ['listing-1'];
render(<CompareFloatingBar />);
await userEvent.click(screen.getByRole('button', { name: 'Clear all' }));
expect(mockStoreState.clearAll).toHaveBeenCalled();
});
it('shows disabled compare button when canCompare is false', () => {
mockStoreState.selectedIds = ['listing-1'];
mockStoreState.canCompare = () => false;
render(<CompareFloatingBar />);
expect(screen.getByRole('button', { name: /Need more/ })).toBeDisabled();
});
it('shows compare now link when canCompare is true', () => {
mockStoreState.selectedIds = ['listing-1', 'listing-2'];
mockStoreState.canCompare = () => true;
render(<CompareFloatingBar />);
expect(screen.getByText('Compare now')).toBeInTheDocument();
});
it('renders remove buttons for each selected item', () => {
mockStoreState.selectedIds = ['listing-1', 'listing-2'];
render(<CompareFloatingBar />);
const removeButtons = screen.getAllByRole('button', { name: 'Remove item' });
expect(removeButtons).toHaveLength(2);
});
it('calls removeFromCompare when remove button is clicked', async () => {
mockStoreState.selectedIds = ['listing-1'];
render(<CompareFloatingBar />);
const removeBtn = screen.getByRole('button', { name: 'Remove item' });
await userEvent.click(removeBtn);
expect(mockStoreState.removeFromCompare).toHaveBeenCalledWith('listing-1');
});
});