diff --git a/web/src/lib/__mocks__/resize-observer.mock.ts b/web/src/lib/__mocks__/resize-observer.mock.ts new file mode 100644 index 0000000000..ffd1dad2fd --- /dev/null +++ b/web/src/lib/__mocks__/resize-observer.mock.ts @@ -0,0 +1,8 @@ +import { vi } from 'vitest'; + +export const getResizeObserverMock = () => + vi.fn(() => ({ + disconnect: vi.fn(), + observe: vi.fn(), + unobserve: vi.fn(), + })); diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.spec.ts b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.spec.ts index 68de2509be..3f49e79ed4 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.spec.ts +++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.spec.ts @@ -1,3 +1,4 @@ +import { getResizeObserverMock } from '$lib/__mocks__/resize-observer.mock'; import { preferences as preferencesStore, resetSavedUser, user as userStore } from '$lib/stores/user.store'; import { renderWithTooltips } from '$tests/helpers'; import { assetFactory } from '@test-data/factories/asset-factory'; @@ -20,10 +21,7 @@ describe('AssetViewerNavBar component', () => { Element.prototype.animate = vi.fn().mockImplementation(() => ({ cancel: () => {}, })); - vi.stubGlobal( - 'ResizeObserver', - vi.fn(() => ({ observe: vi.fn(), unobserve: vi.fn(), disconnect: vi.fn() })), - ); + vi.stubGlobal('ResizeObserver', getResizeObserverMock()); vi.mock(import('$lib/managers/feature-flags-manager.svelte'), () => { return { featureFlagsManager: { diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte index 06f4e5a0b2..848870b654 100644 --- a/web/src/lib/components/asset-viewer/asset-viewer.svelte +++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte @@ -176,6 +176,7 @@ } activityManager.reset(); + assetViewerManager.closeEditor(); }); const handleGetAllAlbums = async () => { diff --git a/web/src/lib/components/asset-viewer/editor/transform-tool/crop-area.spec.ts b/web/src/lib/components/asset-viewer/editor/transform-tool/crop-area.spec.ts new file mode 100644 index 0000000000..009d9b29b8 --- /dev/null +++ b/web/src/lib/components/asset-viewer/editor/transform-tool/crop-area.spec.ts @@ -0,0 +1,39 @@ +import { getResizeObserverMock } from '$lib/__mocks__/resize-observer.mock'; +import CropArea from '$lib/components/asset-viewer/editor/transform-tool/crop-area.svelte'; +import { transformManager } from '$lib/managers/edit/transform-manager.svelte'; +import { getAssetMediaUrl } from '$lib/utils'; +import { assetFactory } from '@test-data/factories/asset-factory'; +import { render } from '@testing-library/svelte'; +import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; + +vi.mock('$lib/utils'); + +describe('CropArea', () => { + beforeAll(() => { + vi.stubGlobal('ResizeObserver', getResizeObserverMock()); + vi.mocked(getAssetMediaUrl).mockReturnValue('/mock-image.jpg'); + }); + + afterEach(() => { + transformManager.reset(); + }); + + it('clears cursor styles on reset', () => { + const asset = assetFactory.build(); + const { getByRole } = render(CropArea, { asset }); + const cropArea = getByRole('button', { name: 'Crop area' }); + + transformManager.region = { x: 100, y: 100, width: 200, height: 200 }; + transformManager.cropImageSize = { width: 1000, height: 1000 }; + transformManager.cropImageScale = 1; + transformManager.updateCursor(100, 150); + + expect(document.body.style.cursor).toBe('ew-resize'); + expect(cropArea.style.cursor).toBe('ew-resize'); + + transformManager.reset(); + + expect(document.body.style.cursor).toBe(''); + expect(cropArea.style.cursor).toBe(''); + }); +}); diff --git a/web/src/lib/managers/edit/transform-manager.svelte.ts b/web/src/lib/managers/edit/transform-manager.svelte.ts index 63e9d2e43f..341eb3aa88 100644 --- a/web/src/lib/managers/edit/transform-manager.svelte.ts +++ b/web/src/lib/managers/edit/transform-manager.svelte.ts @@ -223,6 +223,10 @@ class TransformManager implements EditToolManager { this.dragOffset = { x: 0, y: 0 }; this.resizeSide = ''; this.imgElement = null; + if (this.cropAreaEl) { + this.cropAreaEl.style.cursor = ''; + } + document.body.style.cursor = ''; this.cropAreaEl = null; this.isDragging = false; this.overlayEl = null;