mock mock mock !
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 57m50s

This commit is contained in:
2025-12-19 20:31:04 -08:00
parent e62739810e
commit a3d3ddd772
48 changed files with 1062 additions and 507 deletions

View File

@@ -9,6 +9,9 @@ import type { Flyer, FlyerItem } from '../types';
import type { FlyerDisplayProps } from '../features/flyer/FlyerDisplay'; // Keep this for FlyerDisplay mock
import type { ExtractedDataTableProps } from '../features/flyer/ExtractedDataTable'; // Import the props for ExtractedDataTable
// Unmock the component to test the real implementation
vi.unmock('./HomePage');
// Mock child components to isolate the HomePage logic
vi.mock('../features/flyer/FlyerDisplay', () => ({
FlyerDisplay: (props: FlyerDisplayProps) => <div data-testid="flyer-display" data-image-url={props.imageUrl} />,

View File

@@ -5,7 +5,7 @@ import { ExtractedDataTable } from '../features/flyer/ExtractedDataTable';
import { AnalysisPanel } from '../features/flyer/AnalysisPanel';
import type { Flyer, FlyerItem } from '../types';
interface HomePageProps {
export interface HomePageProps {
selectedFlyer: Flyer | null;
flyerItems: FlyerItem[];
onOpenCorrectionTool: () => void;

View File

@@ -5,6 +5,7 @@ import { describe, it, expect, vi, beforeEach, type Mocked } from 'vitest';
import UserProfilePage from './UserProfilePage';
import * as apiClient from '../services/apiClient';
import { UserProfile, Achievement, UserAchievement } from '../types';
import { createMockUserProfile, createMockUserAchievement } from '../tests/utils/mockFactories';
// Mock dependencies
vi.mock('../services/apiClient'); // This was correct
@@ -28,17 +29,17 @@ vi.mock('../components/AchievementsList', () => ({
const mockedApiClient = apiClient as Mocked<typeof apiClient>;
// --- Mock Data ---
const mockProfile: UserProfile = {
const mockProfile: UserProfile = createMockUserProfile({
user_id: 'user-123',
user: { user_id: 'user-123', email: 'test@example.com' },
full_name: 'Test User',
avatar_url: 'http://example.com/avatar.jpg',
points: 150,
role: 'user',
};
});
const mockAchievements: (UserAchievement & Achievement)[] = [
{
createMockUserAchievement({
achievement_id: 1,
user_id: 'user-123',
achieved_at: '2024-01-01T00:00:00Z',
@@ -46,7 +47,7 @@ const mockAchievements: (UserAchievement & Achievement)[] = [
description: 'Uploaded first flyer.',
icon: 'upload',
points_value: 10,
},
}),
];
describe('UserProfilePage', () => {

View File

@@ -5,18 +5,16 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
import toast from 'react-hot-toast';
import { AdminBrandManager } from './AdminBrandManager';
import * as apiClient from '../../../services/apiClient';
import type { Brand } from '../../../types';
import { createMockBrand } from '../../../tests/utils/mockFactories';
// After mocking, we can get a type-safe mocked version of the module.
// This allows us to use .mockResolvedValue, .mockRejectedValue, etc. on the functions.
// The apiClient is now mocked globally via src/tests/setup/tests-setup-unit.ts.
const mockedApiClient = vi.mocked(apiClient);
const mockedToast = vi.mocked(toast, true);
const mockBrands: Brand[] = [
{ brand_id: 1, name: 'No Frills', store_name: 'No Frills', logo_url: null },
{ brand_id: 2, name: 'Compliments', store_name: 'Sobeys', logo_url: 'http://example.com/compliments.png' },
const mockBrands = [
createMockBrand({ brand_id: 1, name: 'No Frills', store_name: 'No Frills', logo_url: null }),
createMockBrand({ brand_id: 2, name: 'Compliments', store_name: 'Sobeys', logo_url: 'http://example.com/compliments.png' }),
];
describe('AdminBrandManager', () => {

View File

@@ -5,7 +5,7 @@ import { render, screen, fireEvent, waitFor, within } from '@testing-library/rea
import { describe, it, expect, vi, beforeEach, type Mocked } from 'vitest';
import { CorrectionRow } from './CorrectionRow';
import * as apiClient from '../../../services/apiClient';
import type { SuggestedCorrection, MasterGroceryItem, Category } from '../../../types';
import { createMockSuggestedCorrection, createMockMasterGroceryItem, createMockCategory } from '../../../tests/utils/mockFactories';
// Cast the mocked module to its mocked type to retain type safety and autocompletion.
// The apiClient is now mocked globally via src/tests/setup/tests-setup-unit.ts.
@@ -35,26 +35,20 @@ vi.mock('../../../components/ConfirmationModal', () => ({
),
}));
const mockCorrection: SuggestedCorrection = {
const mockCorrection = createMockSuggestedCorrection({
suggested_correction_id: 1,
flyer_item_id: 101,
user_id: 'user-1',
correction_type: 'WRONG_PRICE',
suggested_value: '250', // $2.50
status: 'pending',
created_at: new Date().toISOString(),
flyer_item_name: 'Bananas',
flyer_item_price_display: '$1.99',
user_email: 'test@example.com',
};
});
const mockMasterItems: MasterGroceryItem[] = [
{ master_grocery_item_id: 1, name: 'Bananas', created_at: '', category_id: 1, category_name: 'Produce' },
];
const mockCategories: Category[] = [
{ category_id: 1, name: 'Produce' },
];
const mockMasterItems = [createMockMasterGroceryItem({ master_grocery_item_id: 1, name: 'Bananas', category_id: 1, category_name: 'Produce' })];
const mockCategories = [createMockCategory({ category_id: 1, name: 'Produce' })];
const mockOnProcessed = vi.fn();
@@ -305,10 +299,7 @@ describe('CorrectionRow', () => {
it('should save an edited value for INCORRECT_ITEM_LINK', async () => {
// Add a temporary item to the master list for this test
const localMasterItems = [
...mockMasterItems,
{ master_grocery_item_id: 2, name: 'Milk', created_at: '', category_id: 2, category_name: 'Dairy' },
];
const localMasterItems = [...mockMasterItems, createMockMasterGroceryItem({ master_grocery_item_id: 2, name: 'Milk', category_id: 2, category_name: 'Dairy' })];
mockedApiClient.updateSuggestedCorrection.mockResolvedValue(new Response(JSON.stringify({ ...mockCorrection, correction_type: 'INCORRECT_ITEM_LINK', suggested_value: '2' })));
renderInTable({
@@ -330,10 +321,7 @@ describe('CorrectionRow', () => {
});
it('should save an edited value for ITEM_IS_MISCATEGORIZED', async () => {
const localCategories = [
...mockCategories,
{ category_id: 2, name: 'Dairy' },
];
const localCategories = [...mockCategories, createMockCategory({ category_id: 2, name: 'Dairy' })];
mockedApiClient.updateSuggestedCorrection.mockResolvedValue(new Response(JSON.stringify({ ...mockCorrection, correction_type: 'ITEM_IS_MISCATEGORIZED', suggested_value: '2' })));
renderInTable({

View File

@@ -7,6 +7,11 @@ import * as apiClient from '../../../services/apiClient';
import { notifySuccess, notifyError } from '../../../services/notificationService';
import toast from 'react-hot-toast';
import * as logger from '../../../services/logger.client';
import { createMockProfile, createMockAddress, createMockUser } from '../../../tests/utils/mockFactories';
import { createMockLogger } from '../../../tests/utils/mockLogger';
// Unmock the component to test the real implementation
vi.unmock('./ProfileManager');
const mockedApiClient = vi.mocked(apiClient, true);
@@ -19,12 +24,7 @@ vi.mock('react-hot-toast', () => ({
},
}));
vi.mock('../../../services/logger.client', () => ({
logger: {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
debug: vi.fn(),
},
logger: createMockLogger(),
}));
const mockOnClose = vi.fn();
@@ -33,24 +33,23 @@ const mockOnSignOut = vi.fn();
const mockOnProfileUpdate = vi.fn();
// --- MOCK DATA ---
const authenticatedUser = { user_id: 'auth-user-123', email: 'test@example.com' };
const authenticatedUser = createMockUser({ user_id: 'auth-user-123', email: 'test@example.com' });
const mockAddressId = 123;
const authenticatedProfile = {
const authenticatedProfile = createMockProfile({
user_id: 'auth-user-123',
full_name: 'Test User',
avatar_url: 'http://example.com/avatar.png',
role: 'user' as const,
role: 'user',
points: 100,
preferences: {
darkMode: false,
unitSystem: 'imperial' as const,
unitSystem: 'imperial',
},
address_id: mockAddressId,
};
});
const mockAddress = {
const mockAddress = createMockAddress({
address_id: mockAddressId,
user_id: 'auth-user-123',
address_line_1: '123 Main St',
city: 'Anytown',
province_state: 'ON',
@@ -58,9 +57,7 @@ const mockAddress = {
country: 'Canada',
latitude: 43.0,
longitude: -79.0,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
};
});
const defaultSignedOutProps = {
isOpen: true,

View File

@@ -18,7 +18,7 @@ import { AuthView } from './AuthView';
import { AddressForm } from './AddressForm';
import { useProfileAddress } from '../../../hooks/useProfileAddress';
interface ProfileManagerProps {
export interface ProfileManagerProps {
isOpen: boolean;
onClose: () => void;
user: User | null; // Can be null for login/register