mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-14 00:01:03 +00:00
refactor(maps): move the place clusters out of MapViewGL
The cluster source, its layers, the expansion zoom and the DOM bubbles now live in placeClusterLayers.ts with their own tests, which brings MapViewGL back under its size baseline instead of growing it. Lowers the size and eslint baselines that this change made smaller.
This commit is contained in:
@@ -1,5 +1,27 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { clusterBubbleSize, createClusterBubble } from './placeClusterLayers';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
type ClusterMap,
|
||||
PLACE_CLUSTER_SOURCE_ID,
|
||||
addPlaceClusterLayers,
|
||||
clusterBubbleSize,
|
||||
createClusterBubble,
|
||||
drawClusterBubbles,
|
||||
} from './placeClusterLayers';
|
||||
|
||||
function fakeMap(features: unknown[], expansionZoom: unknown = 11) {
|
||||
const source = { getClusterExpansionZoom: vi.fn(() => expansionZoom) };
|
||||
const map = {
|
||||
addSource: vi.fn(),
|
||||
addLayer: vi.fn(),
|
||||
getSource: vi.fn((id: string) => (id === PLACE_CLUSTER_SOURCE_ID ? source : undefined)),
|
||||
easeTo: vi.fn(),
|
||||
querySourceFeatures: vi.fn((_id: string, query: { filter: unknown[] }) =>
|
||||
query.filter[0] === 'has' ? features : []
|
||||
),
|
||||
};
|
||||
return { map: map as unknown as ClusterMap & typeof map, source };
|
||||
}
|
||||
|
||||
describe('cluster bubbles', () => {
|
||||
it('FE-COMP-PLACECLUSTER-001: a bubble grows in three steps with its count', () => {
|
||||
@@ -15,4 +37,50 @@ describe('cluster bubbles', () => {
|
||||
expect(bubble.style.height).toBe('42px');
|
||||
expect(bubble.textContent).toBe('38');
|
||||
});
|
||||
|
||||
it('FE-COMP-PLACECLUSTER-003: the canvas circle and count stay as an invisible hit area', () => {
|
||||
const { map } = fakeMap([]);
|
||||
addPlaceClusterLayers(map);
|
||||
expect(map.addSource).toHaveBeenCalledWith(PLACE_CLUSTER_SOURCE_ID, expect.objectContaining({ cluster: true }));
|
||||
const layers = map.addLayer.mock.calls.map(([layer]) => layer as { id: string; paint: Record<string, unknown> });
|
||||
expect(layers.find((l) => l.id === 'trip-place-clusters-circle')?.paint['circle-opacity']).toBe(0);
|
||||
expect(layers.find((l) => l.id === 'trip-place-clusters-count')?.paint['text-opacity']).toBe(0);
|
||||
});
|
||||
|
||||
it('FE-COMP-PLACECLUSTER-004: one bubble per cluster, placed at its centre, that zooms in on a click', () => {
|
||||
const cluster = { properties: { cluster_id: 5, point_count: 12 }, geometry: { coordinates: [139.7, 35.6] } };
|
||||
const { map, source } = fakeMap([
|
||||
cluster,
|
||||
cluster, // the same cluster crossing a tile edge
|
||||
{ properties: { cluster_id: 6 }, geometry: { coordinates: [1, 1] } }, // no count
|
||||
{ properties: { cluster_id: 7, point_count: 3 } }, // no geometry
|
||||
]);
|
||||
const placed: { el: HTMLElement; lng: number; lat: number }[] = [];
|
||||
const pins = drawClusterBubbles(map, (el, lng, lat) => {
|
||||
placed.push({ el, lng, lat });
|
||||
return lng;
|
||||
});
|
||||
|
||||
expect(pins).toEqual([139.7]);
|
||||
expect(placed[0].el.textContent).toBe('12');
|
||||
expect(placed[0].lat).toBe(35.6);
|
||||
|
||||
const onMapClick = vi.fn();
|
||||
document.body.appendChild(placed[0].el);
|
||||
document.body.addEventListener('click', onMapClick);
|
||||
placed[0].el.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||
document.body.removeEventListener('click', onMapClick);
|
||||
placed[0].el.remove();
|
||||
|
||||
// The click is the bubble's: the map underneath never sees it.
|
||||
expect(onMapClick).not.toHaveBeenCalled();
|
||||
expect(source.getClusterExpansionZoom).toHaveBeenCalledWith(5, expect.any(Function));
|
||||
expect(map.easeTo).toHaveBeenCalledWith({ center: [139.7, 35.6], zoom: 11, duration: 350 });
|
||||
});
|
||||
|
||||
it('FE-COMP-PLACECLUSTER-005: a source that reports nothing draws nothing', () => {
|
||||
const { map } = fakeMap([]);
|
||||
map.querySourceFeatures.mockReturnValue(null as never);
|
||||
expect(drawClusterBubbles(map, () => 1)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user