// @vitest-environment happy-dom import { describe, it, expect, beforeEach } from 'vitest'; import { ConfirmModal } from '@presentation/components/ConfirmModal'; describe('ConfirmModal', () => { beforeEach(() => { document.body.innerHTML = ''; }); it('show crée un overlay dans le body', async () => { const promise = ConfirmModal.show('Titre', 'Message'); expect(document.querySelector('.confirm-overlay')).toBeTruthy(); // Fermer la modale pour résoudre la promesse (document.querySelector('.confirm-btn-cancel') as HTMLButtonElement).click(); await promise; }); it('affiche le titre et le message', async () => { const promise = ConfirmModal.show('Supprimer', 'Êtes-vous sûr ?'); expect(document.querySelector('.confirm-title')!.textContent).toBe('Supprimer'); expect(document.querySelector('.confirm-msg')!.textContent).toBe('Êtes-vous sûr ?'); (document.querySelector('.confirm-btn-cancel') as HTMLButtonElement).click(); await promise; }); it('Confirmer résout avec true', async () => { const promise = ConfirmModal.show('Test', 'Confirmer ?'); (document.querySelector('.confirm-btn-ok') as HTMLButtonElement).click(); expect(await promise).toBe(true); }); it('Annuler résout avec false', async () => { const promise = ConfirmModal.show('Test', 'Annuler ?'); (document.querySelector('.confirm-btn-cancel') as HTMLButtonElement).click(); expect(await promise).toBe(false); }); it('cliquer sur l\'overlay résout avec false', async () => { const promise = ConfirmModal.show('Test', 'Overlay'); const overlay = document.querySelector('.confirm-overlay') as HTMLElement; // Simuler un clic sur l'overlay (pas la box) overlay.dispatchEvent(new MouseEvent('click', { bubbles: true })); expect(await promise).toBe(false); }); it('overlay perd la classe confirm-hidden quand affiché', async () => { const promise = ConfirmModal.show('Test', 'Visible'); const overlay = document.querySelector('.confirm-overlay')!; expect(overlay.classList.contains('confirm-hidden')).toBe(false); (document.querySelector('.confirm-btn-cancel') as HTMLButtonElement).click(); await promise; }); it('overlay récupère la classe confirm-hidden après fermeture', async () => { const promise = ConfirmModal.show('Test', 'Fermer'); (document.querySelector('.confirm-btn-ok') as HTMLButtonElement).click(); await promise; const overlay = document.querySelector('.confirm-overlay')!; expect(overlay.classList.contains('confirm-hidden')).toBe(true); }); it('utilise textContent et non innerHTML (sécurité XSS)', async () => { const promise = ConfirmModal.show('XSS', ''); const title = document.querySelector('.confirm-title')!; const msg = document.querySelector('.confirm-msg')!; expect(title.textContent).toBe('XSS'); expect(title.innerHTML).not.toContain(''); expect(msg.textContent).toBe(''); expect(msg.innerHTML).not.toContain(' { const promise = ConfirmModal.show('Test', 'Textes'); expect(document.querySelector('.confirm-btn-cancel')!.textContent).toBe('Annuler'); expect(document.querySelector('.confirm-btn-ok')!.textContent).toBe('Confirmer'); (document.querySelector('.confirm-btn-cancel') as HTMLButtonElement).click(); await promise; }); it('icône warning est présente', async () => { const promise = ConfirmModal.show('Test', 'Icône'); expect(document.querySelector('.confirm-icon')!.textContent).toBe('warning'); (document.querySelector('.confirm-btn-cancel') as HTMLButtonElement).click(); await promise; }); });