/**
* Tests for the ConfirmModal component.
*/
import { describe, it, expect, vi, afterEach } from 'vitest';
import { screen, fireEvent, cleanup } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { render } from '../utils';
import { ConfirmModal } from '../../components/ConfirmModal';
describe('ConfirmModal', () => {
const defaultProps = {
title: 'Confirm Action',
message: 'Are you sure you want to proceed?',
onConfirm: vi.fn(),
onCancel: vi.fn(),
};
afterEach(() => {
cleanup();
vi.clearAllMocks();
});
describe('rendering', () => {
it('renders title', () => {
render();
expect(screen.getByText('Confirm Action')).toBeInTheDocument();
});
it('renders message', () => {
render();
expect(
screen.getByText('Are you sure you want to proceed?')
).toBeInTheDocument();
});
it('renders default button text', () => {
render();
expect(screen.getByText('Confirm')).toBeInTheDocument();
expect(screen.getByText('Cancel')).toBeInTheDocument();
});
it('renders custom button text', () => {
render(
);
expect(screen.getByText('Delete')).toBeInTheDocument();
expect(screen.getByText('Go Back')).toBeInTheDocument();
});
});
describe('interactions', () => {
it('calls onConfirm when confirm button is clicked', async () => {
const user = userEvent.setup();
const onConfirm = vi.fn();
render();
await user.click(screen.getByText('Confirm'));
expect(onConfirm).toHaveBeenCalledTimes(1);
});
it('calls onCancel when cancel button is clicked', async () => {
const user = userEvent.setup();
const onCancel = vi.fn();
render();
await user.click(screen.getByText('Cancel'));
expect(onCancel).toHaveBeenCalledTimes(1);
});
it('calls onCancel when clicking backdrop', async () => {
const user = userEvent.setup();
const onCancel = vi.fn();
const { container } = render(
);
// Click on the backdrop (first div with fixed class)
const backdrop = container.querySelector('.fixed');
if (backdrop) {
await user.click(backdrop);
expect(onCancel).toHaveBeenCalledTimes(1);
}
});
it('does not call onCancel when clicking modal content', async () => {
const user = userEvent.setup();
const onCancel = vi.fn();
render();
// Click on the title inside the modal
await user.click(screen.getByText('Confirm Action'));
expect(onCancel).not.toHaveBeenCalled();
});
it('calls onCancel when Escape key is pressed', () => {
const onCancel = vi.fn();
render();
fireEvent.keyDown(window, { key: 'Escape' });
expect(onCancel).toHaveBeenCalledTimes(1);
});
});
describe('variants', () => {
it('renders default variant', () => {
render();
expect(screen.getByText('Confirm Action')).toBeInTheDocument();
});
it('renders danger variant', () => {
render();
expect(screen.getByText('Confirm Action')).toBeInTheDocument();
});
it('renders warning variant', () => {
render();
expect(screen.getByText('Confirm Action')).toBeInTheDocument();
});
});
describe('loading state', () => {
it('shows loading text when isLoading is true', () => {
render();
expect(screen.getByText('Deleting...')).toBeInTheDocument();
});
it('shows default loading text when loadingText not provided', () => {
render();
expect(screen.getByText('Loading...')).toBeInTheDocument();
});
it('disables buttons when loading', () => {
render();
const buttons = screen.getAllByRole('button');
buttons.forEach(button => {
expect(button).toBeDisabled();
});
});
it('does not call onCancel when clicking backdrop while loading', async () => {
const user = userEvent.setup();
const onCancel = vi.fn();
const { container } = render(
);
const backdrop = container.querySelector('.fixed');
if (backdrop) {
await user.click(backdrop);
expect(onCancel).not.toHaveBeenCalled();
}
});
it('does not call onCancel on Escape key while loading', () => {
const onCancel = vi.fn();
render();
fireEvent.keyDown(window, { key: 'Escape' });
expect(onCancel).not.toHaveBeenCalled();
});
});
});