Files
flyer-crawler.projectium.com/src/features/flyer/FlyerDisplay.test.tsx
Torben Sorensen a3d3ddd772
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 57m50s
mock mock mock !
2025-12-19 20:31:04 -08:00

143 lines
6.5 KiB
TypeScript

// src/features/flyer/FlyerDisplay.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { FlyerDisplay } from './FlyerDisplay';
import { createMockStore } from '../../tests/utils/mockFactories';
const mockStore = createMockStore({ store_id: 1, name: 'SuperMart', logo_url: 'http://example.com/logo.png' });
const mockOnOpenCorrectionTool = vi.fn();
const defaultProps = {
imageUrl: 'http://example.com/flyer.jpg',
store: mockStore,
validFrom: '2023-10-26',
validTo: '2023-11-01',
storeAddress: '123 Main St, Anytown',
onOpenCorrectionTool: mockOnOpenCorrectionTool,
};
describe('FlyerDisplay', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should render all elements when all props are provided', () => {
render(<FlyerDisplay {...defaultProps} />);
// Check for store info
expect(screen.getByRole('heading', { name: 'SuperMart' })).toBeInTheDocument();
expect(screen.getByAltText('SuperMart Logo')).toHaveAttribute('src', mockStore.logo_url);
expect(screen.getByText('123 Main St, Anytown')).toBeInTheDocument();
// Check for date range
expect(screen.getByText('Deals valid from October 26, 2023 to November 1, 2023')).toBeInTheDocument();
// Check for flyer image
expect(screen.getByAltText('Grocery Flyer')).toHaveAttribute('src', defaultProps.imageUrl);
});
it('should render a placeholder when imageUrl is null', () => {
render(<FlyerDisplay {...defaultProps} imageUrl={null} />);
expect(screen.getByText('Flyer image will be displayed here')).toBeInTheDocument();
});
it('should not render the header if store and date info are missing', () => {
render(<FlyerDisplay imageUrl={defaultProps.imageUrl} onOpenCorrectionTool={mockOnOpenCorrectionTool} />);
expect(screen.queryByRole('heading')).not.toBeInTheDocument();
});
it('should render without a logo if store.logo_url is not provided', () => {
render(<FlyerDisplay {...defaultProps} store={{ ...mockStore, logo_url: null }} />);
expect(screen.getByRole('heading', { name: 'SuperMart' })).toBeInTheDocument();
expect(screen.queryByAltText('SuperMart Logo')).not.toBeInTheDocument();
});
it('should format a single day validity correctly', () => {
render(<FlyerDisplay {...defaultProps} validFrom="2023-10-26" validTo="2023-10-26" />);
expect(screen.getByText('Valid on October 26, 2023')).toBeInTheDocument();
});
it('should format correctly with only a start date', () => {
render(<FlyerDisplay {...defaultProps} validTo={null} />);
expect(screen.getByText('Deals start October 26, 2023')).toBeInTheDocument();
});
it('should format correctly with only an end date', () => {
render(<FlyerDisplay {...defaultProps} validFrom={null} />);
expect(screen.getByText('Deals end November 1, 2023')).toBeInTheDocument();
});
it('should apply dark mode image styles', () => {
render(<FlyerDisplay {...defaultProps} />);
const image = screen.getByAltText('Grocery Flyer');
expect(image).toHaveClass('dark:invert');
expect(image).toHaveClass('dark:hue-rotate-180');
});
describe('"Correct Data" Button', () => {
it('should be visible when the header is rendered', () => {
render(<FlyerDisplay {...defaultProps} />);
expect(screen.getByRole('button', { name: /correct data/i })).toBeInTheDocument();
});
it('should not be visible when the header is not rendered', () => {
render(<FlyerDisplay imageUrl={defaultProps.imageUrl} onOpenCorrectionTool={mockOnOpenCorrectionTool} />);
expect(screen.queryByRole('button', { name: /correct data/i })).not.toBeInTheDocument();
});
it('should call onOpenCorrectionTool when clicked', () => {
render(<FlyerDisplay {...defaultProps} />);
fireEvent.click(screen.getByRole('button', { name: /correct data/i }));
expect(mockOnOpenCorrectionTool).toHaveBeenCalledTimes(1);
});
});
describe('Image Source Logic', () => {
it('should use the imageUrl directly if it is a full URL', () => {
render(<FlyerDisplay {...defaultProps} imageUrl="https://cdn.example.com/flyer.png" />);
const image = screen.getByAltText('Grocery Flyer');
expect(image).toHaveAttribute('src', 'https://cdn.example.com/flyer.png');
});
it('should use the imageUrl directly if it is an absolute path', () => {
render(<FlyerDisplay {...defaultProps} imageUrl="/assets/flyers/flyer.png" />);
const image = screen.getByAltText('Grocery Flyer');
expect(image).toHaveAttribute('src', '/assets/flyers/flyer.png');
});
it('should prepend the path for a relative imageUrl from the database', () => {
render(<FlyerDisplay {...defaultProps} imageUrl="flyer-from-db.jpg" />);
const image = screen.getByAltText('Grocery Flyer');
expect(image).toHaveAttribute('src', '/flyer-images/flyer-from-db.jpg');
});
});
describe('Date Formatting Robustness', () => {
it('should handle invalid date strings gracefully by not displaying them', () => {
render(<FlyerDisplay {...defaultProps} validFrom="invalid-date" validTo="another-bad-date" />);
expect(screen.queryByText(/deals valid from/i)).not.toBeInTheDocument();
expect(screen.queryByText(/valid on/i)).not.toBeInTheDocument();
expect(screen.queryByText(/deals start/i)).not.toBeInTheDocument();
expect(screen.queryByText(/deals end/i)).not.toBeInTheDocument();
expect(screen.queryByText(/invalid date/i)).not.toBeInTheDocument(); // Ensure no "Invalid Date" text
});
it('should handle a mix of valid and invalid date strings gracefully (start date valid)', () => {
render(<FlyerDisplay {...defaultProps} validFrom="2023-10-26" validTo="invalid-date" />);
expect(screen.getByText('Deals start October 26, 2023')).toBeInTheDocument();
expect(screen.queryByText(/deals valid from/i)).not.toBeInTheDocument();
expect(screen.queryByText(/deals end/i)).not.toBeInTheDocument();
expect(screen.queryByText(/invalid date/i)).not.toBeInTheDocument();
});
it('should handle a mix of valid and invalid date strings gracefully (end date valid)', () => {
render(<FlyerDisplay {...defaultProps} validFrom="another-bad-date" validTo="2023-11-01" />);
expect(screen.getByText('Deals end November 1, 2023')).toBeInTheDocument();
expect(screen.queryByText(/deals valid from/i)).not.toBeInTheDocument();
expect(screen.queryByText(/deals start/i)).not.toBeInTheDocument();
expect(screen.queryByText(/invalid date/i)).not.toBeInTheDocument();
});
});
});