From 24461ecf7633ef0c2d1d4cef9bfc681e32acfbd0 Mon Sep 17 00:00:00 2001 From: Maurice Date: Fri, 9 Oct 2026 17:53:52 +0200 Subject: [PATCH] fix(admin): the default map template offers the Amap presets users can pick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the admin's default user settings, the map template dropdown listed seven tile presets, while every user's own map settings listed nine: the same seven plus Amap and Amap Satellite. An admin running an instance for people in mainland China could not pick the one basemap that works well there as the default, short of pasting its URL by hand. The Amap presets (57eac32f9) were added to the two user preset copies and not to the admin's separate copy; nothing in that change or later gives a reason, and the server stores any template as a default. The later refactor kept the gap as DEFAULT_MAP_PRESETS beside MAP_PRESETS. There is now one MAP_PRESETS list, read by the user settings and the admin defaults on both desktop and phone. Regression test FE-ADMIN-DUS-029 (DefaultUserSettingsTab.test.tsx) was red on the old code: "Unable to find role="button" and name "高德地图 (Amap)"". Changed assertions: - useMapSettingsForm.test.ts FE-COMP-MAPFORM-001: it expected the admin list DEFAULT_MAP_PRESETS to hold 7 presets and the user list to add Amap on top; it now expects the one list to hold 9 presets including both Amap templates. --- .../Admin/DefaultUserSettingsTab.test.tsx | 15 ++++++++++++++- .../components/Admin/DefaultUserSettingsTab.tsx | 2 +- .../src/components/Settings/mapSettingsModel.ts | 12 +++++------- .../Settings/useMapSettingsForm.test.ts | 15 ++++----------- .../screens/admin/MAdminDefaultUserSettings.tsx | 2 +- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/client/src/components/Admin/DefaultUserSettingsTab.test.tsx b/client/src/components/Admin/DefaultUserSettingsTab.test.tsx index e52b0160b..d6b3b84d5 100644 --- a/client/src/components/Admin/DefaultUserSettingsTab.test.tsx +++ b/client/src/components/Admin/DefaultUserSettingsTab.test.tsx @@ -1,4 +1,4 @@ -// FE-ADMIN-DUS-001 to FE-ADMIN-DUS-028 +// FE-ADMIN-DUS-001 to FE-ADMIN-DUS-029 import { render, screen, waitFor, within, fireEvent } from '../../../tests/helpers/render'; import userEvent from '@testing-library/user-event'; import { http, HttpResponse } from 'msw'; @@ -6,6 +6,7 @@ import { server } from '../../../tests/helpers/msw/server'; import { resetAllStores, seedStore } from '../../../tests/helpers/store'; import { buildAdmin } from '../../../tests/helpers/factories'; import { useAuthStore } from '../../store/authStore'; +import { AMAP_ROAD } from '../../constants/mapDefaults'; import { ToastContainer } from '../shared/Toast'; import DefaultUserSettingsTab from './DefaultUserSettingsTab'; @@ -220,6 +221,18 @@ describe('DefaultUserSettingsTab', () => { expect(screen.getByTestId('map-preview')).toHaveAttribute('data-tile', url); }); + it('FE-ADMIN-DUS-029: the Amap presets a user can pick are offered as instance defaults too', async () => { + const user = userEvent.setup(); + const { puts } = stubDefaults(); + render(); + await screen.findByText('Default User Settings'); + + await pickFromSelect(user, 'Select template...', '高德地图 (Amap)'); + + await waitFor(() => expect(puts).toEqual([{ map_tile_url: AMAP_ROAD }])); + expect(screen.getByTestId('map-preview')).toHaveAttribute('data-tile', AMAP_ROAD); + }); + it('FE-ADMIN-DUS-011: a hand-typed tile URL is saved on blur', async () => { const user = userEvent.setup(); const { puts } = stubDefaults(); diff --git a/client/src/components/Admin/DefaultUserSettingsTab.tsx b/client/src/components/Admin/DefaultUserSettingsTab.tsx index 1a08f61ff..c4038d99d 100644 --- a/client/src/components/Admin/DefaultUserSettingsTab.tsx +++ b/client/src/components/Admin/DefaultUserSettingsTab.tsx @@ -12,7 +12,7 @@ import type { DistanceUnit, WeekStart } from '../../types' import { weekStartOptions } from '../../utils/calendarWeek' import { withTileApiKey } from '../../utils/tileUrl' import { defaultStyleForProvider } from '../Map/glProviders' -import { DEFAULT_MAP_PRESETS as MAP_PRESETS, type MapProvider } from '../Settings/mapSettingsModel' +import { MAP_PRESETS, type MapProvider } from '../Settings/mapSettingsModel' import RoutingInstanceFields from './RoutingInstanceFields' import { useDefaultUserSettings, type Defaults } from './useDefaultUserSettings' diff --git a/client/src/components/Settings/mapSettingsModel.ts b/client/src/components/Settings/mapSettingsModel.ts index 1f1a9aac9..b75cf2a43 100644 --- a/client/src/components/Settings/mapSettingsModel.ts +++ b/client/src/components/Settings/mapSettingsModel.ts @@ -18,8 +18,11 @@ export interface MapPreset { url: string; } -/** The tile presets an admin can make the default for every user. */ -export const DEFAULT_MAP_PRESETS: MapPreset[] = [ +/** + * The tile presets a user picks from in their own map settings, and the same list + * an admin picks the default for every user from. + */ +export const MAP_PRESETS: MapPreset[] = [ { name: 'OpenStreetMap', url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png' }, { name: 'OpenStreetMap DE', url: 'https://tile.openstreetmap.de/{z}/{x}/{y}.png' }, // The app default, and a vector style rather than a {z}/{x}/{y} template: no @@ -31,11 +34,6 @@ export const DEFAULT_MAP_PRESETS: MapPreset[] = [ { name: 'CartoDB Light', url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png' }, { name: 'CartoDB Dark', url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png' }, { name: 'Stadia Smooth', url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png' }, -]; - -/** The tile presets a user picks from in their own map settings. */ -export const MAP_PRESETS: MapPreset[] = [ - ...DEFAULT_MAP_PRESETS, // Amap (高德). GCJ-02 tiles: the map switches to a shifted projection for // these so markers still land on the right street (see gcj02Crs.ts). The only // basemap here that is genuinely good inside mainland China. diff --git a/client/src/components/Settings/useMapSettingsForm.test.ts b/client/src/components/Settings/useMapSettingsForm.test.ts index 3ffd5204b..8ba662614 100644 --- a/client/src/components/Settings/useMapSettingsForm.test.ts +++ b/client/src/components/Settings/useMapSettingsForm.test.ts @@ -3,18 +3,12 @@ import { act, renderHook } from '@testing-library/react'; import { buildSettings } from '../../../tests/helpers/factories'; import { resetAllStores, seedStore } from '../../../tests/helpers/store'; +import { AMAP_ROAD, AMAP_SATELLITE } from '../../constants/mapDefaults'; import { useAuthStore } from '../../store/authStore'; import { useSettingsStore } from '../../store/settingsStore'; import type { Settings } from '../../types'; import { MAPBOX_DEFAULT_STYLE, OPENFREEMAP_DEFAULT_STYLE } from '../Map/glProviders'; -import { - DEFAULT_MAP_PRESETS, - MAP_PRESETS, - PREVIEW_CENTER, - normalizeProvider, - slotStyle, - styleForProvider, -} from './mapSettingsModel'; +import { MAP_PRESETS, PREVIEW_CENTER, normalizeProvider, slotStyle, styleForProvider } from './mapSettingsModel'; import { useMapSettingsForm } from './useMapSettingsForm'; const toast = vi.hoisted(() => ({ success: vi.fn(), error: vi.fn() })); @@ -36,10 +30,9 @@ beforeEach(() => { }); describe('mapSettingsModel', () => { - it('FE-COMP-MAPFORM-001: the user list adds the two Amap presets to the admin list', () => { - expect(MAP_PRESETS.slice(0, DEFAULT_MAP_PRESETS.length)).toEqual(DEFAULT_MAP_PRESETS); - expect(DEFAULT_MAP_PRESETS).toHaveLength(7); + it('FE-COMP-MAPFORM-001: one preset list, the two Amap presets included, serves users and the admin defaults', () => { expect(MAP_PRESETS).toHaveLength(9); + expect(MAP_PRESETS.map((p) => p.url)).toEqual(expect.arrayContaining([AMAP_ROAD, AMAP_SATELLITE])); }); it('FE-COMP-MAPFORM-002: provider and style rules', () => { diff --git a/client/src/mobile/screens/admin/MAdminDefaultUserSettings.tsx b/client/src/mobile/screens/admin/MAdminDefaultUserSettings.tsx index 2c1c2fbfe..0bd99367f 100644 --- a/client/src/mobile/screens/admin/MAdminDefaultUserSettings.tsx +++ b/client/src/mobile/screens/admin/MAdminDefaultUserSettings.tsx @@ -7,7 +7,7 @@ import { getApiErrorMessage, type DistanceUnit, type WeekStart } from '../../../ import { weekStartOptions } from '../../../utils/calendarWeek' import { withTileApiKey } from '../../../utils/tileUrl' import { defaultStyleForProvider } from '../../../components/Map/glProviders' -import { DEFAULT_MAP_PRESETS as MAP_PRESETS, type MapProvider } from '../../../components/Settings/mapSettingsModel' +import { MAP_PRESETS, type MapProvider } from '../../../components/Settings/mapSettingsModel' import { useDefaultUserSettings, type Defaults } from '../../../components/Admin/useDefaultUserSettings' import MToggle from '../../components/MToggle' import MSegmented from '../../components/MSegmented'