mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 05:56:53 +00:00
1f66ef1d32
CARTO stamps an "API KEY REQUIRED" watermark onto every basemap tile fetched without a key since 26.08.2026, and both CartoDB presets plus the built-in fallback are CARTO. The key is free and needs no account, so add it as a setting rather than dropping the provider. carto_api_key sits next to mapbox_access_token: per user in Settings/Map, instance-wide under Admin/User Defaults, encrypted at rest, injected from CARTO_API_KEY on managed instances. Unlike Mapbox it never switches the map provider, since a raster key says nothing about the renderer. The key is appended as ?key= at render time instead of being stored in the template, so a saved URL stays portable and survives a rotation. That is also what reaches the four maps that pinned CARTO and ignored the user's tile setting: atlas, collections, the public trip share and the public journey. The two share pages read it from their token-gated payload, the same way baseCurrency already travels. Also lifts the release notice above page chrome. Its overlay sat at z-index 50, under the Vacay mode toolbar at 61, so the dialog was neither on top nor modal. Adds a six-step layer scale to index.css and moves the three notice shells onto it. Closes #2054 Closes #2052
95 lines
3.6 KiB
TypeScript
95 lines
3.6 KiB
TypeScript
import { describe, it, expect, beforeEach } from 'vitest'
|
|
import { renderHook, act } from '@testing-library/react'
|
|
import { useTileUrl, useCartoApiKey } from './useTileUrl'
|
|
import { useSettingsStore } from '../store/settingsStore'
|
|
import { CARTO_LIGHT, CARTO_DARK } from '../constants/mapDefaults'
|
|
import type { Settings } from '../types'
|
|
|
|
const OSM = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
|
|
const SELF_HOSTED = 'https://tiles.example.com/{z}/{x}/{y}.png'
|
|
|
|
const initialState = useSettingsStore.getState()
|
|
|
|
function setSettings(patch: Partial<Settings>) {
|
|
useSettingsStore.setState((s) => ({ settings: { ...s.settings, ...patch } }))
|
|
}
|
|
|
|
describe('useTileUrl', () => {
|
|
beforeEach(() => {
|
|
useSettingsStore.setState(initialState, true)
|
|
})
|
|
|
|
it('FE-TILEURL-001: falls back to the caller default while nothing is configured', () => {
|
|
const { result } = renderHook(() => useTileUrl(OSM))
|
|
expect(result.current).toBe(OSM)
|
|
})
|
|
|
|
it('FE-TILEURL-002: the user template wins over the fallback', () => {
|
|
setSettings({ map_tile_url: SELF_HOSTED })
|
|
const { result } = renderHook(() => useTileUrl(CARTO_LIGHT))
|
|
expect(result.current).toBe(SELF_HOSTED)
|
|
})
|
|
|
|
it('FE-TILEURL-003: appends the CARTO key to a CARTO fallback', () => {
|
|
setSettings({ carto_api_key: 'abc123' })
|
|
const { result } = renderHook(() => useTileUrl(CARTO_LIGHT))
|
|
expect(result.current).toBe(`${CARTO_LIGHT}?key=abc123`)
|
|
})
|
|
|
|
it('FE-TILEURL-004: keeps the key away from a self-hosted template', () => {
|
|
setSettings({ map_tile_url: SELF_HOSTED, carto_api_key: 'abc123' })
|
|
const { result } = renderHook(() => useTileUrl(CARTO_LIGHT))
|
|
expect(result.current).toBe(SELF_HOSTED)
|
|
})
|
|
|
|
it('FE-TILEURL-005: ignoreUserTemplate pins the fallback but still gets the key', () => {
|
|
// Atlas and collections pin a basemap of their own; they must not lose the
|
|
// key just because they ignore map_tile_url.
|
|
setSettings({ map_tile_url: SELF_HOSTED, carto_api_key: 'abc123' })
|
|
const { result } = renderHook(() => useTileUrl(CARTO_DARK, true))
|
|
expect(result.current).toBe(`${CARTO_DARK}?key=abc123`)
|
|
})
|
|
|
|
it('FE-TILEURL-006: normalizes a legacy sharded OSM template', () => {
|
|
setSettings({ map_tile_url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' })
|
|
const { result } = renderHook(() => useTileUrl(CARTO_LIGHT))
|
|
expect(result.current).toBe(OSM)
|
|
})
|
|
|
|
it('FE-TILEURL-007: follows a key change without a remount', () => {
|
|
setSettings({ carto_api_key: 'first' })
|
|
const { result } = renderHook(() => useTileUrl(CARTO_LIGHT))
|
|
expect(result.current).toBe(`${CARTO_LIGHT}?key=first`)
|
|
|
|
act(() => setSettings({ carto_api_key: 'second' }))
|
|
expect(result.current).toBe(`${CARTO_LIGHT}?key=second`)
|
|
|
|
act(() => setSettings({ carto_api_key: '' }))
|
|
expect(result.current).toBe(CARTO_LIGHT)
|
|
})
|
|
|
|
it('FE-TILEURL-008: follows a template change without a remount', () => {
|
|
const { result } = renderHook(() => useTileUrl(CARTO_LIGHT))
|
|
act(() => setSettings({ map_tile_url: SELF_HOSTED }))
|
|
expect(result.current).toBe(SELF_HOSTED)
|
|
})
|
|
})
|
|
|
|
describe('useCartoApiKey', () => {
|
|
beforeEach(() => {
|
|
useSettingsStore.setState(initialState, true)
|
|
})
|
|
|
|
it('FE-TILEURL-009: reports an empty string while no key is stored', () => {
|
|
setSettings({ carto_api_key: undefined })
|
|
const { result } = renderHook(() => useCartoApiKey())
|
|
expect(result.current).toBe('')
|
|
})
|
|
|
|
it('FE-TILEURL-010: reports the stored key', () => {
|
|
setSettings({ carto_api_key: 'abc123' })
|
|
const { result } = renderHook(() => useCartoApiKey())
|
|
expect(result.current).toBe('abc123')
|
|
})
|
|
})
|