feat(image-modal): add swipe-to-dismiss functionality for zoomed images

This commit is contained in:
2026-09-02 14:39:10 -03:00
parent ebae063a0f
commit 7d52e11bca
3 changed files with 73 additions and 8 deletions

View File

@@ -1,13 +1,14 @@
import '@angular/compiler';
import { ComponentFixture, TestBed, getTestBed } from '@angular/core/testing';
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
import { afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
import { ImageModalData, MODAL_DATA } from '../../../core/services/modal.service';
import { ImageModalData, MODAL_DATA, ModalRef } from '../../../core/services/modal.service';
import { ImageModalComponent } from './image-modal.component';
describe('ImageModalComponent', () => {
let fixture: ComponentFixture<ImageModalComponent>;
const modalRef = { dismiss: vi.fn() };
const data: ImageModalData = {
src: '/images/producto.webp',
alt: 'Vista frontal del producto',
@@ -25,9 +26,13 @@ describe('ImageModalComponent', () => {
});
beforeEach(async () => {
modalRef.dismiss.mockReset();
await TestBed.configureTestingModule({
imports: [ImageModalComponent],
providers: [{ provide: MODAL_DATA, useValue: data }],
providers: [
{ provide: MODAL_DATA, useValue: data },
{ provide: ModalRef, useValue: modalRef },
],
}).compileComponents();
fixture = TestBed.createComponent(ImageModalComponent);
@@ -85,6 +90,30 @@ describe('ImageModalComponent', () => {
expect(zoom.textContent).toContain('150%');
});
it('dismisses with a downward swipe while the image is at its base zoom', () => {
const viewport = fixture.nativeElement.querySelector('.image-modal__viewport') as HTMLElement;
viewport.dispatchEvent(pointerEvent('pointerdown', 1, 150, 100));
viewport.dispatchEvent(pointerEvent('pointermove', 1, 155, 230));
viewport.dispatchEvent(pointerEvent('pointerup', 1, 155, 230));
expect(modalRef.dismiss).toHaveBeenCalledWith('swipe');
});
it('does not dismiss with a downward gesture while the image is zoomed', () => {
const element = fixture.nativeElement as HTMLElement;
const viewport = element.querySelector('.image-modal__viewport') as HTMLElement;
const zoomIn = element.querySelector('[aria-label="Acercar"]') as HTMLButtonElement;
zoomIn.click();
fixture.detectChanges();
viewport.dispatchEvent(pointerEvent('pointerdown', 1, 150, 100));
viewport.dispatchEvent(pointerEvent('pointermove', 1, 155, 230));
viewport.dispatchEvent(pointerEvent('pointerup', 1, 155, 230));
expect(modalRef.dismiss).not.toHaveBeenCalled();
});
it('shows a fallback when the image cannot be loaded', () => {
const image = fixture.nativeElement.querySelector('img') as HTMLImageElement;
image.dispatchEvent(new Event('error'));