From c7ed458c8eed5f2515b255805470451b69a5a8ce Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Fri, 22 May 2026 10:14:53 +0300 Subject: [PATCH] test: ImageLightbox failing tests --- .../ImageLightbox/ui/ImageLightbox.test.tsx | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/shared/ui/ImageLightbox/ui/ImageLightbox.test.tsx diff --git a/src/shared/ui/ImageLightbox/ui/ImageLightbox.test.tsx b/src/shared/ui/ImageLightbox/ui/ImageLightbox.test.tsx new file mode 100644 index 0000000..07e1537 --- /dev/null +++ b/src/shared/ui/ImageLightbox/ui/ImageLightbox.test.tsx @@ -0,0 +1,68 @@ +import { fireEvent, render, screen } from '@testing-library/react'; +import { ImageLightbox } from './ImageLightbox'; + +// jsdom does not implement dialog methods — mock them +beforeAll(() => { + HTMLDialogElement.prototype.showModal = vi.fn(); + HTMLDialogElement.prototype.close = vi.fn(); +}); + +beforeEach(() => { + vi.clearAllMocks(); +}); + +const DEFAULT_PROPS = { src: '/project.jpg', alt: 'My Project' }; + +describe('ImageLightbox', () => { + describe('thumbnail', () => { + it('renders a thumbnail image', () => { + render(); + expect(screen.getByRole('img', { name: 'My Project' })).toBeInTheDocument(); + }); + + it('thumbnail button has cursor-zoom-in', () => { + render(); + const btn = screen.getByRole('button', { name: 'My Project' }); + expect(btn).toHaveClass('cursor-zoom-in'); + }); + + it('forwards className to the thumbnail button', () => { + render(); + expect(screen.getByRole('button', { name: 'My Project' })).toHaveClass('extra-class'); + }); + }); + + describe('dialog', () => { + it('clicking the thumbnail opens the dialog', () => { + render(); + fireEvent.click(screen.getByRole('button', { name: 'My Project' })); + expect(HTMLDialogElement.prototype.showModal).toHaveBeenCalledTimes(1); + }); + + it('clicking the close button closes the dialog', () => { + render(); + fireEvent.click(screen.getByRole('button', { name: /close/i })); + expect(HTMLDialogElement.prototype.close).toHaveBeenCalledTimes(1); + }); + + it('clicking the backdrop (dialog element itself) closes the dialog', () => { + render(); + const dialog = document.querySelector('dialog')!; + fireEvent.click(dialog, { target: dialog }); + expect(HTMLDialogElement.prototype.close).toHaveBeenCalledTimes(1); + }); + + it('clicking inside the dialog (not backdrop) does not close', () => { + render(); + const dialog = document.querySelector('dialog')!; + const inner = dialog.querySelector('div')!; + fireEvent.click(inner); + expect(HTMLDialogElement.prototype.close).not.toHaveBeenCalled(); + }); + + it('dialog has accessible label matching alt text', () => { + render(); + expect(document.querySelector('dialog')).toHaveAttribute('aria-label', 'My Project'); + }); + }); +});