|
1 | 1 | /// <reference types="google.maps" /> |
2 | 2 | import { mountSuspended } from '@nuxt/test-utils/runtime' |
3 | | -import { beforeEach, describe, expect, it, vi } from 'vitest' |
| 3 | +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' |
4 | 4 | import { defineComponent, h, nextTick, provide, shallowRef } from 'vue' |
5 | 5 | import ScriptGoogleMapsOverlayView from '../../packages/script/src/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue' |
6 | 6 | import { MAP_INJECTION_KEY, normalizeLatLng } from '../../packages/script/src/runtime/components/GoogleMaps/useGoogleMapsResource' |
@@ -347,4 +347,63 @@ describe('scriptGoogleMapsOverlayView', () => { |
347 | 347 | expect(content.dataset.state).toBe('open') |
348 | 348 | }) |
349 | 349 | }) |
| 350 | + |
| 351 | + describe('panOnOpen guard for closed/unpositioned overlays', () => { |
| 352 | + // Regression: `onAdd()` previously scheduled `panMapToFitOverlay` whenever |
| 353 | + // `panOnOpen` was enabled, even if the overlay started closed or never |
| 354 | + // resolved a position. That caused unexpected map panning on initial mount |
| 355 | + // and remount. The fix gates the rAF scheduling on `open !== false` and |
| 356 | + // re-checks `open` + `overlayPosition` inside the callback before panning. |
| 357 | + |
| 358 | + let rafSpy: ReturnType<typeof vi.spyOn> |
| 359 | + |
| 360 | + beforeEach(() => { |
| 361 | + rafSpy = vi.spyOn(globalThis, 'requestAnimationFrame') |
| 362 | + }) |
| 363 | + |
| 364 | + afterEach(() => { |
| 365 | + rafSpy.mockRestore() |
| 366 | + }) |
| 367 | + |
| 368 | + it('does not schedule pan-on-open when overlay starts closed (defaultOpen=false)', async () => { |
| 369 | + const mocks = createOverlayMocks() |
| 370 | + await mountOverlay( |
| 371 | + { position: { lat: 10, lng: 20 }, defaultOpen: false }, |
| 372 | + mocks, |
| 373 | + ) |
| 374 | + |
| 375 | + expect(rafSpy).not.toHaveBeenCalled() |
| 376 | + expect(mocks.mockMap.panBy).not.toHaveBeenCalled() |
| 377 | + }) |
| 378 | + |
| 379 | + it('does not schedule pan-on-open when controlled :open is false on mount', async () => { |
| 380 | + const mocks = createOverlayMocks() |
| 381 | + await mountOverlay( |
| 382 | + { position: { lat: 10, lng: 20 }, open: false }, |
| 383 | + mocks, |
| 384 | + ) |
| 385 | + |
| 386 | + expect(rafSpy).not.toHaveBeenCalled() |
| 387 | + expect(mocks.mockMap.panBy).not.toHaveBeenCalled() |
| 388 | + }) |
| 389 | + |
| 390 | + it('schedules pan-on-open when overlay starts open with a position', async () => { |
| 391 | + const mocks = createOverlayMocks() |
| 392 | + await mountOverlay({ position: { lat: 10, lng: 20 } }, mocks) |
| 393 | + |
| 394 | + // The guard allows the rAF to be scheduled when the happy path applies |
| 395 | + expect(rafSpy).toHaveBeenCalled() |
| 396 | + }) |
| 397 | + |
| 398 | + it('respects panOnOpen=false even when overlay is open and positioned', async () => { |
| 399 | + const mocks = createOverlayMocks() |
| 400 | + await mountOverlay( |
| 401 | + { position: { lat: 10, lng: 20 }, panOnOpen: false }, |
| 402 | + mocks, |
| 403 | + ) |
| 404 | + |
| 405 | + expect(rafSpy).not.toHaveBeenCalled() |
| 406 | + expect(mocks.mockMap.panBy).not.toHaveBeenCalled() |
| 407 | + }) |
| 408 | + }) |
350 | 409 | }) |
0 commit comments