Files
flyer-crawler.projectium.com/src/tests/utils/componentMocks.tsx
Torben Sorensen c78323275b
Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 2m28s
more unit tests - done for now
2026-01-29 16:21:48 -08:00

254 lines
8.3 KiB
TypeScript

// src/tests/utils/componentMocks.tsx
import React from 'react';
import { Outlet } from 'react-router-dom';
import { createMockProfile, createMockUserProfile } from './mockFactories';
import type { SuggestedCorrection } from '../../types';
import type { HeaderProps } from '../../components/Header';
import type { ProfileManagerProps } from '../../pages/admin/components/ProfileManager';
import type { VoiceAssistantProps } from '../../features/voice-assistant/VoiceAssistant';
import type { FlyerCorrectionToolProps } from '../../components/FlyerCorrectionTool';
import type { WhatsNewModalProps } from '../../components/WhatsNewModal';
import type { AdminRouteProps } from '../../components/AdminRoute';
import type { MainLayoutProps } from '../../layouts/MainLayout';
import type { HomePageProps } from '../../pages/HomePage';
import type { FlyerDisplayProps } from '../../features/flyer/FlyerDisplay';
import type { StatCardProps } from '../../pages/admin/components/StatCard';
import type { ExtractedDataTableProps } from '../../features/flyer/ExtractedDataTable';
export const MockHeader: React.FC<HeaderProps> = (props) => (
<header data-testid="header-mock">
<button onClick={props.onOpenProfile}>Open Profile</button>
<button onClick={props.onOpenVoiceAssistant}>Open Voice Assistant</button>
</header>
);
export const MockProfileManager: React.FC<Partial<ProfileManagerProps>> = ({
isOpen,
onClose,
onProfileUpdate,
onLoginSuccess,
}) => {
if (!isOpen) return null;
return (
<div data-testid="profile-manager-mock">
<button onClick={onClose}>Close Profile</button>
<button
onClick={() =>
onProfileUpdate?.(createMockProfile({ role: 'user', points: 0, full_name: 'Updated' }))
}
>
Update Profile
</button>
<button
onClick={() =>
onLoginSuccess?.(
createMockUserProfile({ user: { user_id: '1', email: 'a@b.com' } }),
'token',
false,
)
}
>
Login
</button>
</div>
);
};
export const MockVoiceAssistant: React.FC<VoiceAssistantProps> = ({ isOpen, onClose }) =>
isOpen ? (
<div data-testid="voice-assistant-mock">
<button onClick={onClose}>Close Voice Assistant</button>
</div>
) : null;
export const MockFlyerCorrectionTool: React.FC<Partial<FlyerCorrectionToolProps>> = ({
isOpen,
onClose,
onDataExtracted,
}) =>
isOpen ? (
<div data-testid="flyer-correction-tool-mock">
<button onClick={onClose}>Close Correction</button>
<button onClick={() => onDataExtracted?.('store_name', 'New Store Name')}>
Extract Store
</button>
<button onClick={() => onDataExtracted?.('dates', '2023-01-01')}>Extract Dates</button>
</div>
) : null;
export const MockWhatsNewModal: React.FC<Partial<WhatsNewModalProps>> = ({ isOpen, onClose }) =>
isOpen ? (
<div data-testid="whats-new-modal-mock">
<button onClick={onClose}>Close What's New</button>
</div>
) : null;
// Add mock implementations for the remaining simple page/layout components
export const MockAdminPage: React.FC = () => <div data-testid="admin-page-mock">Admin Page</div>;
export const MockAdminRoute: React.FC<Partial<AdminRouteProps>> = () => (
<div data-testid="admin-route-mock">
<Outlet />
</div>
);
export const MockCorrectionsPage: React.FC = () => (
<div data-testid="corrections-page-mock">Corrections Page</div>
);
export const MockAdminStatsPage: React.FC = () => (
<div data-testid="admin-stats-page-mock">Admin Stats Page</div>
);
export const MockResetPasswordPage: React.FC = () => (
<div data-testid="reset-password-page-mock">Reset Password Page</div>
);
export const MockVoiceLabPage: React.FC = () => (
<div data-testid="voice-lab-page-mock">Voice Lab Page</div>
);
export const MockMainLayout: React.FC<Partial<MainLayoutProps>> = () => (
<div data-testid="main-layout-mock">
<Outlet />
</div>
);
export const MockHomePage: React.FC<Partial<HomePageProps>> = ({
selectedFlyer,
onOpenCorrectionTool,
}) => (
<div data-testid="home-page-mock" data-selected-flyer-id={selectedFlyer?.flyer_id}>
Mock Home Page
<button onClick={onOpenCorrectionTool}>Open Correction Tool</button>
</div>
);
export const MockSystemCheck: React.FC = () => (
<div data-testid="system-check-mock">System Health Checks</div>
);
interface MockCorrectionRowProps {
correction: SuggestedCorrection;
onProcessed: (id: number) => void;
}
export const MockCorrectionRow: React.FC<MockCorrectionRowProps> = ({
correction,
onProcessed,
}) => (
<tr data-testid={`correction-row-${correction.suggested_correction_id}`}>
<td>{correction.flyer_item_name}</td>
<td>
<button
data-testid={`process-btn-${correction.suggested_correction_id}`}
onClick={() => onProcessed(correction.suggested_correction_id)}
>
Process
</button>
</td>
</tr>
);
export const MockFlyerDisplay: React.FC<Partial<FlyerDisplayProps>> = ({
imageUrl,
onOpenCorrectionTool,
}) => (
<div data-testid="flyer-display" data-image-url={imageUrl}>
<button data-testid="mock-open-correction-tool" onClick={onOpenCorrectionTool}>
Open Correction Tool
</button>
</div>
);
export const MockAnalysisPanel: React.FC = () => <div data-testid="analysis-panel" />;
export const MockExtractedDataTable: React.FC<Partial<ExtractedDataTableProps>> = ({
items = [],
}) => <div data-testid="extracted-data-table">{items.length} items</div>;
/**
* A simple mock for the StatCard component that renders its props.
*/
export const MockStatCard: React.FC<StatCardProps> = ({ title, value, icon }) => (
<div data-testid="stat-card-mock">
<h3>{title}</h3>
<p>{value}</p>
{icon}
</div>
);
// --- Icon Mocks ---
export const MockShieldExclamationIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg data-testid="shield-icon" {...props} />
);
export const MockChartBarIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg data-testid="chart-icon" {...props} />
);
export const MockUsersIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg data-testid="users-icon" {...props} />
);
export const MockDocumentDuplicateIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg data-testid="document-duplicate-icon" {...props} />
);
export const MockBuildingStorefrontIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg data-testid="building-storefront-icon" {...props} />
);
export const MockBellAlertIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg data-testid="bell-alert-icon" {...props} />
);
export const MockBookOpenIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
<svg data-testid="book-open-icon" {...props} />
);
export const MockFooter: React.FC = () => <footer data-testid="footer-mock">Mock Footer</footer>;
// --- FlyerList and FlyerUploader Mocks ---
import type { Flyer, UserProfile } from '../../types';
interface MockFlyerListProps {
flyers: Flyer[];
onFlyerSelect: (flyer: Flyer) => void;
selectedFlyerId: number | null;
profile: UserProfile | null;
}
export const MockFlyerList: React.FC<MockFlyerListProps> = ({
flyers,
onFlyerSelect,
selectedFlyerId,
profile,
}) => (
<div
data-testid="flyer-list"
data-selected-id={selectedFlyerId ?? 'none'}
data-flyer-count={flyers.length}
data-profile-role={profile?.role ?? 'none'}
>
<h3>Mock Flyer List</h3>
{flyers.length === 0 ? (
<p data-testid="no-flyers-message">No flyers available</p>
) : (
<ul>
{flyers.map((flyer) => (
<li
key={flyer.flyer_id}
data-testid={`flyer-item-${flyer.flyer_id}`}
data-selected={selectedFlyerId === flyer.flyer_id}
>
<button onClick={() => onFlyerSelect(flyer)}>
{flyer.store?.name ?? 'Unknown Store'} - {flyer.item_count} items
</button>
</li>
))}
</ul>
)}
</div>
);
interface MockFlyerUploaderProps {
onProcessingComplete: () => void;
}
export const MockFlyerUploader: React.FC<MockFlyerUploaderProps> = ({ onProcessingComplete }) => (
<div data-testid="flyer-uploader">
<h3>Mock Flyer Uploader</h3>
<button data-testid="mock-upload-complete-btn" onClick={onProcessingComplete}>
Simulate Upload Complete
</button>
</div>
);