/** * BulkActionBar Component Tests * * Tests for the BulkActionBar component that displays a floating action bar * when items are selected in a table. */ import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import { BulkActionBar } from './BulkActionBar'; import { describe, it, expect, vi } from 'vitest'; // Mock the Button component vi.mock('@/ui/Button', () => ({ Button: ({ children, onClick, variant, size, icon }: any) => ( ), })); // Mock the BulkActions component vi.mock('@/ui/BulkActions', () => ({ BulkActions: ({ selectedCount, isOpen, children }: any) => (
{children}
), })); describe('BulkActionBar', () => { const defaultProps = { selectedCount: 0, actions: [], onClearSelection: vi.fn(), }; it('should not render when no items selected', () => { render(); expect(screen.queryByTestId('bulk-actions')).toBeFalsy(); }); it('should render when items are selected', () => { const props = { ...defaultProps, selectedCount: 3, }; render(); expect(screen.getByTestId('bulk-actions')).toBeTruthy(); }); it('should display selected count', () => { const props = { ...defaultProps, selectedCount: 5, }; render(); expect(screen.getByTestId('bulk-actions')).toHaveAttribute('data-count', '5'); }); it('should render with single action', () => { const props = { ...defaultProps, selectedCount: 2, actions: [ { label: 'Delete', onClick: vi.fn(), variant: 'danger' as const, }, ], }; render(); expect(screen.getByText('Delete')).toBeTruthy(); }); it('should render with multiple actions', () => { const props = { ...defaultProps, selectedCount: 3, actions: [ { label: 'Export', onClick: vi.fn(), variant: 'primary' as const, }, { label: 'Archive', onClick: vi.fn(), variant: 'secondary' as const, }, { label: 'Delete', onClick: vi.fn(), variant: 'danger' as const, }, ], }; render(); expect(screen.getByText('Export')).toBeTruthy(); expect(screen.getByText('Archive')).toBeTruthy(); expect(screen.getByText('Delete')).toBeTruthy(); }); it('should render cancel button', () => { const props = { ...defaultProps, selectedCount: 2, actions: [ { label: 'Delete', onClick: vi.fn(), }, ], }; render(); expect(screen.getByText('Cancel')).toBeTruthy(); }); it('should call action onClick when clicked', () => { const actionOnClick = vi.fn(); const props = { ...defaultProps, selectedCount: 2, actions: [ { label: 'Delete', onClick: actionOnClick, }, ], }; render(); const deleteButton = screen.getByText('Delete'); fireEvent.click(deleteButton); expect(actionOnClick).toHaveBeenCalled(); }); it('should call onClearSelection when cancel is clicked', () => { const onClearSelection = vi.fn(); const props = { ...defaultProps, selectedCount: 2, actions: [ { label: 'Delete', onClick: vi.fn(), }, ], onClearSelection, }; render(); const cancelButton = screen.getByText('Cancel'); fireEvent.click(cancelButton); expect(onClearSelection).toHaveBeenCalled(); }); it('should render actions with different variants', () => { const props = { ...defaultProps, selectedCount: 2, actions: [ { label: 'Primary', onClick: vi.fn(), variant: 'primary' as const, }, { label: 'Secondary', onClick: vi.fn(), variant: 'secondary' as const, }, { label: 'Danger', onClick: vi.fn(), variant: 'danger' as const, }, ], }; render(); expect(screen.getByText('Primary')).toBeTruthy(); expect(screen.getByText('Secondary')).toBeTruthy(); expect(screen.getByText('Danger')).toBeTruthy(); }); it('should render actions without variant (defaults to primary)', () => { const props = { ...defaultProps, selectedCount: 2, actions: [ { label: 'Default', onClick: vi.fn(), }, ], }; render(); expect(screen.getByText('Default')).toBeTruthy(); }); it('should render with empty actions array', () => { const props = { ...defaultProps, selectedCount: 2, actions: [], }; render(); expect(screen.getByTestId('bulk-actions')).toBeTruthy(); expect(screen.getByText('Cancel')).toBeTruthy(); }); it('should render with large selected count', () => { const props = { ...defaultProps, selectedCount: 100, actions: [ { label: 'Delete', onClick: vi.fn(), }, ], }; render(); expect(screen.getByTestId('bulk-actions')).toHaveAttribute('data-count', '100'); }); });