mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-12 23:31:02 +00:00
e28bd2fc99
MapLibre 6 and Mapbox GL 3 both throw out of their Map constructor without WebGL2. Every place that builds a GL map now asks one helper first, components/Map/glSupport.ts, and a browser without WebGL2 gets the Leaflet map with the user's tiles instead of a map that fails to start: - the trip map (MapViewAuto) and the journey maps (JourneyMapAuto) pick their renderer through useGlRenderer, which folds in the Mapbox token rule they each had; - the settings preview, desktop and phone, shows the Leaflet preview through useMapSettingsForm and says why under it; - the tour planner keeps the 2D map when 3D is asked for and says that 3D needs WebGL2; - the PDF route map and the Leaflet vector basemap already fell back and now report a GPU failure too. Behind the probe, buildGlMap wraps each constructor (MapViewGL, JourneyMapGL, the settings preview, the terrain map, the PDF map). A GPU that claims WebGL2 and still refuses the context is reported through utils/webgl, which turns the answer to no and tells every mounted map, so they switch to Leaflet without a reload; any other error is still thrown. Two new strings, map.webgl2.fallback and map.webgl2.terrain, in all 27 locales.
48 lines
2.0 KiB
TypeScript
48 lines
2.0 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import type { TripOverviewDay } from '../Map/tripRouteGeometry'
|
|
|
|
vi.mock('../../utils/webgl', () => ({ hasWebGL: vi.fn(() => true), resetWebGLProbe: vi.fn(), reportWebGLFailure: vi.fn() }))
|
|
|
|
const { hasWebGL } = await import('../../utils/webgl')
|
|
const { renderTripMapImage } = await import('./tripMapImage')
|
|
|
|
const day = (over: Partial<TripOverviewDay> = {}): TripOverviewDay => ({
|
|
dayId: 1, dayNumber: 1, date: null, title: null, color: { line: '#0a84ff', casing: '#0a5cc2' },
|
|
lines: [[[48.86, 2.35], [48.88, 2.40]]],
|
|
segments: [], distance: 0, duration: 0, modes: [], ...over,
|
|
})
|
|
|
|
const opts = { width: 720, height: 420, style: null, formatDistance: (km: number) => `${km} km` }
|
|
|
|
beforeEach(() => {
|
|
vi.mocked(hasWebGL).mockReturnValue(true)
|
|
document.body.innerHTML = ''
|
|
})
|
|
|
|
describe('renderTripMapImage', () => {
|
|
it('FE-PDF-MAPIMG-001: gives up without WebGL, before touching the map engine', async () => {
|
|
vi.mocked(hasWebGL).mockReturnValue(false)
|
|
expect(await renderTripMapImage([day()], opts)).toBeNull()
|
|
})
|
|
|
|
it('FE-PDF-MAPIMG-002: gives up when there is no route to frame', async () => {
|
|
expect(await renderTripMapImage([], opts)).toBeNull()
|
|
expect(await renderTripMapImage([day({ lines: [[[48.86, 2.35]]] })], opts)).toBeNull()
|
|
})
|
|
|
|
it('FE-PDF-MAPIMG-003: returns null rather than throwing when the engine fails', async () => {
|
|
// jsdom has no WebGL implementation behind the probe, so constructing the map
|
|
// throws — the export must survive that and fall back to the outline map.
|
|
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
expect(await renderTripMapImage([day()], opts)).toBeNull()
|
|
warn.mockRestore()
|
|
})
|
|
|
|
it('FE-PDF-MAPIMG-004: leaves no offscreen container behind', async () => {
|
|
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
await renderTripMapImage([day()], opts)
|
|
expect(document.body.children).toHaveLength(0)
|
|
warn.mockRestore()
|
|
})
|
|
})
|