import { Position } from '../common'; import { render, screen, userEvent } from '../test-utils'; import Card from '.'; describe('Card', () => { const defaultProps = { title: 'A Card', details: 'Some details about this card', icon: , isExpanded: false, onClick: jest.fn(), }; const dataTestId = 'testCard'; const renderCard = (props = {}) => { return render(); }; it('renders as a div by default', () => { renderCard({ 'data-testid': dataTestId }); expect(screen.getByTestId(dataTestId).tagName).toBe('DIV'); }); it('renders as a tag passed to it', () => { renderCard({ as: 'li', 'data-testid': dataTestId }); expect(screen.getByTestId(dataTestId).tagName).toBe('LI'); }); it('adds the passed id to the card element', () => { const id = 'card-id'; renderCard({ id, 'data-testid': dataTestId }); expect(screen.getByTestId(dataTestId).id).toBe(id); }); it('adds the passed className to the card element', () => { const className = 'card-class'; renderCard({ className, 'data-testid': dataTestId }); expect(screen.getByTestId(dataTestId)).toHaveClass(className); }); it('renders the card title', () => { renderCard(); expect(screen.getByText(defaultProps.title)).toBeInTheDocument(); }); it('renders the card details', () => { renderCard(); expect(screen.getByText(defaultProps.details)).toBeInTheDocument(); }); it('renders the card icon', () => { renderCard({ icon: mock icon }); expect(screen.getByText('mock icon')).toBeInTheDocument(); }); describe('when there is no children prop', () => { it('renders Option title as a heading 4', () => { const onClick = jest.fn(); renderCard(onClick); expect(screen.queryByRole('button')).not.toBeInTheDocument(); expect(screen.getByText(defaultProps.title).tagName).toBe('DIV'); expect(screen.getByText(defaultProps.title)).toHaveAttribute('role', 'heading'); expect(screen.getByText(defaultProps.title)).toHaveAttribute('aria-level', '4'); }); it('has an inactive class', () => { renderCard({ 'data-testid': dataTestId }); expect(screen.getByTestId(dataTestId)).toHaveClass('np-card--inactive'); }); it("doesn't call onClick when clicked", async () => { renderCard(); await userEvent.click(screen.getByText(defaultProps.title)); expect(defaultProps.onClick).not.toHaveBeenCalled(); }); it("doesn't render a chevron", () => { renderCard(); expect(screen.queryByTestId('mock-chevron')).not.toBeInTheDocument(); }); }); describe('when there is children prop', () => { it('calls on onClick with inverse of current isExpanded value when clicked', async () => { const onClick = jest.fn(); renderCard({ 'aria-label': 'test', title: 'test title', children: 'mock children', isExpanded: false, onClick, }); await userEvent.click(screen.getByRole('button', { name: 'test' })); expect(onClick).toHaveBeenCalledWith(true); }); it('renders a chevron', () => { renderCard({ children: 'mock children' }); expect(screen.getByTestId('chevron-up-icon')).toHaveClass(Position.BOTTOM); }); describe('when collapsed', () => { const CONTENT = 'mock children'; it('should not render children', async () => { renderCard({ children: CONTENT }); expect(screen.queryByText(CONTENT)).not.toBeInTheDocument(); }); it('should render appropriate aria attributes', async () => { renderCard({ children: CONTENT }); const button = screen.getByRole('button'); expect(button).toHaveAttribute('aria-expanded', 'false'); expect(button).not.toHaveAttribute('aria-controls'); }); }); describe('when expanded', () => { const defaultProps = { children: 'mock children', isExpanded: true, }; it('flips chevron', () => { renderCard(defaultProps); expect(screen.getByTestId('chevron-up-icon')).toHaveClass(Position.TOP); }); it('renders children', () => { renderCard(defaultProps); expect(screen.getByText(defaultProps.children)).toBeInTheDocument(); }); it('should render appropriate aria attributes', async () => { const { container } = renderCard(defaultProps); const button = screen.getByRole('button'); const controlledId = button.getAttribute('aria-controls'); expect(button).toHaveAttribute('aria-expanded', 'true'); const contentId = screen.getByText(defaultProps.children).getAttribute('id'); expect(contentId).toBe(controlledId); }); }); }); });