import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { describe, expect, it, vi } from 'vitest';
import { MdTileVertical } from '../MdTileVertical';
describe('MdTileVertical', () => {
describe('rendering', () => {
it('renders tile', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical')).toBeInTheDocument();
});
it('renders heading', () => {
render();
expect(screen.getByText('Test Heading')).toBeInTheDocument();
});
it('renders description', () => {
render();
expect(screen.getByText('Test description')).toBeInTheDocument();
});
it('does not render description when empty', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical__content-description')).not.toBeInTheDocument();
});
it('renders icon', () => {
render(★} />);
expect(screen.getByTestId('icon')).toBeInTheDocument();
});
it('renders as button by default', () => {
render();
expect(screen.getByRole('button')).toBeInTheDocument();
});
it('renders as anchor when href provided', () => {
render();
expect(screen.getByRole('link')).toBeInTheDocument();
});
});
describe('modes', () => {
it('applies medium mode by default', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical--small')).not.toBeInTheDocument();
expect(container.querySelector('.md-tile-vertical--large')).not.toBeInTheDocument();
});
it('applies small mode', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical--small')).toBeInTheDocument();
});
it('applies large mode', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical--large')).toBeInTheDocument();
});
});
describe('themes', () => {
it('applies primary theme by default', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical--secondary')).not.toBeInTheDocument();
});
it('applies secondary theme', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical--secondary')).toBeInTheDocument();
});
});
describe('states', () => {
it('applies disabled state', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical--disabled')).toBeInTheDocument();
});
it('disables button when disabled', () => {
render();
expect(screen.getByRole('button')).toBeDisabled();
});
it('sets tabIndex -1 when disabled', () => {
render();
expect(screen.getByRole('button')).toHaveAttribute('tabIndex', '-1');
});
it('shows loading spinner when loading', () => {
const { container } = render();
expect(container.querySelector('.md-loading-spinner')).toBeInTheDocument();
});
it('hides icon when loading', () => {
render(★} loading />);
expect(screen.queryByTestId('icon')).not.toBeInTheDocument();
});
});
describe('interactions', () => {
it('calls onClick when clicked', async () => {
const user = userEvent.setup();
const onClick = vi.fn();
render();
await user.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalled();
});
it('prevents default when preventDefault is true', async () => {
const user = userEvent.setup();
const onClick = vi.fn();
render();
await user.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalled();
});
it('does not trigger onClick when disabled button is clicked', async () => {
const user = userEvent.setup();
const onClick = vi.fn();
render();
await user.click(screen.getByRole('button'));
expect(onClick).not.toHaveBeenCalled();
});
});
describe('link behavior', () => {
it('sets href on anchor', () => {
render();
expect(screen.getByRole('link')).toHaveAttribute('href', 'https://example.com');
});
it('applies disabled styling to link', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical--disabled')).toBeInTheDocument();
});
it('sets tabIndex -1 on disabled link', () => {
render();
expect(screen.getByRole('link')).toHaveAttribute('tabIndex', '-1');
});
});
describe('asChild', () => {
it('renders custom element when asChild is true', () => {
render(} />);
expect(screen.getByTestId('custom-element')).toBeInTheDocument();
});
it('merges className with child element', () => {
const { container } = render(
} />,
);
expect(container.querySelector('.md-tile-vertical.child-class')).toBeInTheDocument();
});
});
describe('accessibility', () => {
it('has icon aria-hidden', () => {
const { container } = render(★} />);
expect(container.querySelector('.md-tile-vertical__content-icon')).toHaveAttribute('aria-hidden', 'true');
});
});
describe('props forwarding', () => {
it('applies custom className', () => {
const { container } = render();
expect(container.querySelector('.md-tile-vertical')).toHaveClass('custom-class');
});
it('forwards other props to button', () => {
render();
expect(screen.getByTestId('tile')).toBeInTheDocument();
});
it('forwards props to anchor', () => {
render();
expect(screen.getByRole('link')).toHaveAttribute('target', '_blank');
});
});
});