mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-22 06:56:35 +00:00
test(journey): pin the viewless-map window the photo layer fell into
The Leaflet mock had no getCenter, so the new guard bailed out of every draw and FE-COMP-JOURNEYMAP-046/047 went red. Give the mock a loaded map by default and add FE-COMP-JOURNEYMAP-050, which takes the view away for exactly the window #2254 hit: render must survive it drawing nothing, and the moveend listener must still put the thumbnail up once fitBounds lands.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// FE-COMP-JOURNEYMAP-001 to FE-COMP-JOURNEYMAP-049
|
||||
// FE-COMP-JOURNEYMAP-001 to FE-COMP-JOURNEYMAP-050
|
||||
|
||||
vi.mock('../../api/websocket', () => ({
|
||||
connect: vi.fn(),
|
||||
@@ -27,6 +27,10 @@ vi.mock('leaflet', () => {
|
||||
setView: vi.fn(),
|
||||
flyTo: vi.fn(),
|
||||
getZoom: vi.fn(() => 10),
|
||||
// Leaflet throws "Set map center and zoom first." out of these until the map
|
||||
// has a view; the loaded map is the default here, FE-COMP-JOURNEYMAP-050
|
||||
// takes it away for the window that #2254 fell into.
|
||||
getCenter: vi.fn(() => ({ lat: 0, lng: 0 })),
|
||||
zoomIn: vi.fn(),
|
||||
zoomOut: vi.fn(),
|
||||
// The photo layer subscribes to zoom/pan and clusters in screen space (#1614).
|
||||
@@ -58,6 +62,7 @@ import { render, act, fireEvent, waitFor } from '../../../tests/helpers/render';
|
||||
import { resetAllStores, seedStore } from '../../../tests/helpers/store';
|
||||
import { useSettingsStore } from '../../store/settingsStore';
|
||||
import { buildSettings } from '../../../tests/helpers/factories';
|
||||
import type { Mock } from 'vitest';
|
||||
import L from 'leaflet';
|
||||
import JourneyMap from './JourneyMap';
|
||||
import type { JourneyMapHandle } from './JourneyMap';
|
||||
@@ -693,4 +698,47 @@ describe('JourneyMap', () => {
|
||||
expect(html).toHaveLength(1);
|
||||
expect(html[0]).not.toMatch(/>\d+</);
|
||||
});
|
||||
|
||||
// #2254 — the map effect defers its opening fitBounds/setView to a rAF, so this
|
||||
// effect can draw while the map still has no center or zoom. Clustering
|
||||
// projects to container pixels, which throws in that window and took the whole
|
||||
// public journey page down with it.
|
||||
it('FE-COMP-JOURNEYMAP-050: waits out a map that has no view yet, then draws on moveend', () => {
|
||||
const noView = () => { throw new Error('Set map center and zoom first.'); };
|
||||
let hasView = false;
|
||||
const photoHtml = () =>
|
||||
vi.mocked(L.divIcon).mock.calls.map(c => String(c[0]?.html)).filter(h => h.includes('/uploads/'));
|
||||
|
||||
// The mock hands out one shared map instance, so it can be reached — and
|
||||
// stripped of its view — before the component ever builds one. Typed down to
|
||||
// the three spies this needs: L.map's signature promises a real Leaflet map.
|
||||
type MapProbe = { getCenter: Mock; latLngToContainerPoint: Mock; on: Mock };
|
||||
L.map(document.createElement('div'));
|
||||
const map = mockedMap() as MapProbe;
|
||||
vi.mocked(L.map).mockClear();
|
||||
map.getCenter.mockImplementation(() => (hasView ? { lat: 0, lng: 0 } : noView()));
|
||||
map.latLngToContainerPoint.mockImplementation(() => (hasView ? { x: 0, y: 0 } : noView()));
|
||||
|
||||
try {
|
||||
// Rendering must survive the viewless window, and draw nothing in it.
|
||||
expect(() =>
|
||||
render(
|
||||
<JourneyMap checkins={[]} entries={[]} photos={[{ id: 'p1', lat: 1, lng: 2, thumbUrl: '/uploads/late.jpg' }]} />,
|
||||
),
|
||||
).not.toThrow();
|
||||
expect(photoHtml()).toHaveLength(0);
|
||||
|
||||
// The deferred fitBounds lands: the listener this effect registered redraws.
|
||||
hasView = true;
|
||||
const redraw = map.on.mock.calls.find(c => c[0] === 'moveend')?.[1] as () => void;
|
||||
expect(redraw).toBeTypeOf('function');
|
||||
act(() => { redraw(); });
|
||||
|
||||
expect(photoHtml()).toHaveLength(1);
|
||||
expect(photoHtml()[0]).toContain('/uploads/late.jpg');
|
||||
} finally {
|
||||
map.getCenter.mockImplementation(() => ({ lat: 0, lng: 0 }));
|
||||
map.latLngToContainerPoint.mockImplementation(() => ({ x: 0, y: 0 }));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user