Files
flyer-crawler.projectium.com/src/features/charts/TopDeals.test.tsx

246 lines
7.3 KiB
TypeScript

// src/components/TopDeals.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { TopDeals } from './TopDeals';
import type { FlyerItem } from '../../types';
import { createMockFlyerItem } from '../../tests/utils/mockFactories';
describe('TopDeals', () => {
const mockFlyerItems: FlyerItem[] = [
createMockFlyerItem({
flyer_item_id: 1,
item: 'Apples',
price_display: '$1.00',
price_in_cents: 100,
quantity: '1 lb',
category_name: 'Produce',
flyer_id: 1,
master_item_id: 1,
unit_price: { value: 100, unit: 'lb' },
}),
createMockFlyerItem({
flyer_item_id: 2,
item: 'Milk',
price_display: '$2.50',
price_in_cents: 250,
quantity: '1L',
category_name: 'Dairy',
flyer_id: 1,
master_item_id: 2,
unit_price: { value: 250, unit: 'L' },
}),
createMockFlyerItem({
flyer_item_id: 3,
item: 'Bread',
price_display: '$2.00',
price_in_cents: 200,
quantity: '1 loaf',
category_name: 'Bakery',
flyer_id: 1,
master_item_id: 3,
unit_price: { value: 200, unit: 'count' },
}),
createMockFlyerItem({
flyer_item_id: 4,
item: 'Eggs',
price_display: '$3.00',
price_in_cents: 300,
quantity: '1 dozen',
category_name: 'Dairy',
flyer_id: 1,
master_item_id: 4,
unit_price: { value: 25, unit: 'count' },
}),
createMockFlyerItem({
flyer_item_id: 5,
item: 'Cheese',
price_display: '$4.00',
price_in_cents: 400,
quantity: '200g',
category_name: 'Dairy',
flyer_id: 1,
master_item_id: 5,
unit_price: { value: 200, unit: '100g' },
}),
createMockFlyerItem({
flyer_item_id: 6,
item: 'Yogurt',
price_display: '$1.50',
price_in_cents: 150,
quantity: '500g',
category_name: 'Dairy',
flyer_id: 1,
master_item_id: 6,
unit_price: { value: 30, unit: '100g' },
}),
createMockFlyerItem({
flyer_item_id: 7,
item: 'Oranges',
price_display: '$1.20',
price_in_cents: 120,
quantity: '1 lb',
category_name: 'Produce',
flyer_id: 1,
master_item_id: 7,
unit_price: { value: 120, unit: 'lb' },
}),
createMockFlyerItem({
flyer_item_id: 8,
item: 'Cereal',
price_display: '$3.50',
price_in_cents: 350,
quantity: '300g',
category_name: 'Breakfast',
flyer_id: 1,
master_item_id: 8,
unit_price: { value: 117, unit: '100g' },
}),
createMockFlyerItem({
flyer_item_id: 9,
item: 'Coffee',
price_display: '$5.00',
price_in_cents: 500,
quantity: '250g',
category_name: 'Beverages',
flyer_id: 1,
master_item_id: 9,
unit_price: { value: 200, unit: '100g' },
}),
createMockFlyerItem({
flyer_item_id: 10,
item: 'Tea',
price_display: '$2.20',
price_in_cents: 220,
quantity: '20 bags',
category_name: 'Beverages',
flyer_id: 1,
master_item_id: 10,
unit_price: { value: 11, unit: 'count' },
}),
createMockFlyerItem({
flyer_item_id: 11,
item: 'Pasta',
price_display: '$1.80',
price_in_cents: 180,
quantity: '500g',
category_name: 'Pantry',
flyer_id: 1,
master_item_id: 11,
unit_price: { value: 36, unit: '100g' },
}),
createMockFlyerItem({
flyer_item_id: 12,
item: 'Water',
price_display: '$0.99',
price_in_cents: 99,
quantity: '1L',
category_name: 'Beverages',
flyer_id: 1,
master_item_id: 12,
unit_price: { value: 99, unit: 'L' },
}),
createMockFlyerItem({
flyer_item_id: 13,
item: 'Soda',
price_display: '$0.75',
price_in_cents: 75,
quantity: '355ml',
category_name: 'Beverages',
flyer_id: 1,
master_item_id: 13,
unit_price: { value: 21, unit: '100ml' },
}),
createMockFlyerItem({
flyer_item_id: 14,
item: 'Chips',
price_display: '$2.10',
price_in_cents: 210,
quantity: '150g',
category_name: 'Snacks',
flyer_id: 1,
master_item_id: 14,
unit_price: { value: 140, unit: '100g' },
}),
createMockFlyerItem({
flyer_item_id: 15,
item: 'Candy',
price_display: '$0.50',
price_in_cents: 50,
quantity: '50g',
category_name: 'Snacks',
flyer_id: 1,
master_item_id: 15,
unit_price: { value: 100, unit: '100g' },
}),
];
it('should not render if the items array is empty', () => {
const { container } = render(<TopDeals items={[]} />);
expect(container.firstChild).toBeNull();
});
it('should not render if no items have price_in_cents', () => {
const itemsWithoutPrices: FlyerItem[] = [
createMockFlyerItem({
flyer_item_id: 1,
item: 'Free Sample',
price_display: 'FREE',
price_in_cents: null,
}),
createMockFlyerItem({
flyer_item_id: 2,
item: 'Info Brochure',
price_display: '',
price_in_cents: null,
}),
];
const { container } = render(<TopDeals items={itemsWithoutPrices} />);
expect(container.firstChild).toBeNull();
});
it('should render the correct heading', () => {
render(<TopDeals items={mockFlyerItems.slice(0, 5)} />);
expect(
screen.getByRole('heading', { name: /top 10 deals across all flyers/i }),
).toBeInTheDocument();
});
it('should display up to 10 items, sorted by price_in_cents ascending', () => {
render(<TopDeals items={mockFlyerItems} />);
const listItems = screen.getAllByRole('listitem');
expect(listItems).toHaveLength(10); // Should only show top 10
// Corrected expected order of items based on price_in_cents:
// Candy (50), Soda (75), Water (99), Apples (100), Oranges (120), Yogurt (150), Pasta (180), Bread (200), Chips (210), Tea (220)
expect(listItems[0]).toHaveTextContent('Candy');
expect(listItems[0]).toHaveTextContent('$0.50');
expect(listItems[1]).toHaveTextContent('Soda');
expect(listItems[1]).toHaveTextContent('$0.75');
expect(listItems[2]).toHaveTextContent('Water');
expect(listItems[2]).toHaveTextContent('$0.99');
expect(listItems[3]).toHaveTextContent('Apples');
expect(listItems[3]).toHaveTextContent('$1.00');
expect(listItems[4]).toHaveTextContent('Oranges');
expect(listItems[4]).toHaveTextContent('$1.20');
expect(listItems[5]).toHaveTextContent('Yogurt');
expect(listItems[5]).toHaveTextContent('$1.50');
expect(listItems[6]).toHaveTextContent('Pasta');
expect(listItems[6]).toHaveTextContent('$1.80');
expect(listItems[7]).toHaveTextContent('Bread');
expect(listItems[7]).toHaveTextContent('$2.00');
expect(listItems[8]).toHaveTextContent('Chips');
expect(listItems[8]).toHaveTextContent('$2.10');
expect(listItems[9]).toHaveTextContent('Tea');
expect(listItems[9]).toHaveTextContent('$2.20');
});
it('should display item name, price_display, and quantity for each deal', () => {
render(<TopDeals items={mockFlyerItems.slice(0, 1)} />); // Render just one item for simplicity
expect(screen.getByText('Apples')).toBeInTheDocument();
expect(screen.getByText('$1.00')).toBeInTheDocument();
expect(screen.getByText('(Qty: 1 lb)')).toBeInTheDocument();
});
});