IcostPro/__tests__/components/DeleteConfirmModal.test.tsx
2026-02-12 21:40:57 +01:00

103 lines
3.5 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, fireEvent, waitFor, cleanup, within } from '@testing-library/react';
import DeleteConfirmModal from '@/components/DeleteConfirmModal';
describe('DeleteConfirmModal', () => {
const defaultProps = {
open: true,
ingredientName: 'Organic Butter',
onClose: vi.fn(),
onConfirm: vi.fn(() => Promise.resolve()),
};
beforeEach(() => {
vi.clearAllMocks();
});
afterEach(() => {
cleanup();
});
it('renders nothing when open=false', () => {
const { container } = render(
<DeleteConfirmModal {...defaultProps} open={false} />
);
expect(container.innerHTML).toBe('');
});
it('shows ingredient name in confirmation text', () => {
const { container } = render(<DeleteConfirmModal {...defaultProps} />);
expect(within(container).getByText('Organic Butter')).toBeInTheDocument();
});
it('calls onConfirm when Delete clicked', async () => {
const { container } = render(<DeleteConfirmModal {...defaultProps} />);
const buttons = within(container).getAllByRole('button');
const deleteBtn = buttons.find(b => b.textContent === 'Delete')!;
fireEvent.click(deleteBtn);
await waitFor(() => {
expect(defaultProps.onConfirm).toHaveBeenCalledOnce();
});
});
it('shows "Deleting..." during async operation', async () => {
let resolveDelete!: () => void;
const slowConfirm = vi.fn(() => new Promise<void>((resolve) => {
resolveDelete = resolve;
}));
const { container } = render(<DeleteConfirmModal {...defaultProps} onConfirm={slowConfirm} />);
const buttons = within(container).getAllByRole('button');
const deleteBtn = buttons.find(b => b.textContent === 'Delete')!;
fireEvent.click(deleteBtn);
await waitFor(() => {
const btns = within(container).getAllByRole('button');
expect(btns.find(b => b.textContent === 'Deleting...')).toBeDefined();
});
resolveDelete();
await waitFor(() => {
const btns = within(container).getAllByRole('button');
expect(btns.find(b => b.textContent === 'Delete')).toBeDefined();
});
});
it('disables both buttons during deletion', async () => {
let resolveDelete!: () => void;
const slowConfirm = vi.fn(() => new Promise<void>((resolve) => {
resolveDelete = resolve;
}));
const { container } = render(<DeleteConfirmModal {...defaultProps} onConfirm={slowConfirm} />);
const buttons = within(container).getAllByRole('button');
const deleteBtn = buttons.find(b => b.textContent === 'Delete')!;
fireEvent.click(deleteBtn);
await waitFor(() => {
const btns = within(container).getAllByRole('button');
const cancelBtn = btns.find(b => b.textContent === 'Cancel')!;
const deletingBtn = btns.find(b => b.textContent === 'Deleting...')!;
expect(cancelBtn).toBeDisabled();
expect(deletingBtn).toBeDisabled();
});
resolveDelete();
await waitFor(() => {
const btns = within(container).getAllByRole('button');
const cancelBtn = btns.find(b => b.textContent === 'Cancel')!;
expect(cancelBtn).not.toBeDisabled();
});
});
it('calls onClose when Cancel clicked', () => {
const { container } = render(<DeleteConfirmModal {...defaultProps} />);
const buttons = within(container).getAllByRole('button');
const cancelBtn = buttons.find(b => b.textContent === 'Cancel')!;
fireEvent.click(cancelBtn);
expect(defaultProps.onClose).toHaveBeenCalledOnce();
});
});