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);
});
});
});
});