From c7b3c111e279058d81a1ebed242851165382e668 Mon Sep 17 00:00:00 2001 From: Kayd-06 Date: Sun, 22 Feb 2026 14:11:19 +0530 Subject: [PATCH] Fix region-specific presets in Recently Used list (#11405) --- modules/presets/index.js | 11 +++++- test/spec/presets/index.js | 78 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/modules/presets/index.js b/modules/presets/index.js index fb7e2faf1d8..bf127752bbd 100644 --- a/modules/presets/index.js +++ b/modules/presets/index.js @@ -1,4 +1,5 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; +import { isEqual } from 'lodash-es'; import { prefs } from '../core/preferences'; import { fileFetcher } from '../core/file_fetcher'; @@ -428,7 +429,15 @@ export function presetIndex() { if (Array.isArray(loc)) { const validHere = locationManager.locationSetsAt(loc); - result.collection = result.collection.filter(a => !a.locationSetID || validHere[a.locationSetID]); + result.collection = result.collection.map(a => { + if (a.locationSetID && !validHere[a.locationSetID]) { + const equivalent = _this.matchTags(a.tags, geometry, loc); + if (equivalent && !equivalent.isFallback() && isEqual(a.tags, equivalent.tags)) { + return equivalent; + } + } + return a; + }).filter(a => !a.locationSetID || validHere[a.locationSetID]); } return result; diff --git a/test/spec/presets/index.js b/test/spec/presets/index.js index 0214c2fa238..31d16319c98 100644 --- a/test/spec/presets/index.js +++ b/test/spec/presets/index.js @@ -425,4 +425,82 @@ describe('iD.presetIndex', function () { }); }); + describe('Issue #11405: Region-specific Presets in Recently Used List', function () { + it('replaces an invalid regional preset in defaults with a valid equivalent', async () => { + // Define a base preset and a regional variant + var testPresets = { + 'highway/motorway_link': { + name: 'Motorway Link', + tags: { highway: 'motorway_link' }, + geometry: ['line'] + }, + 'highway/motorway_link-US': { + name: 'Motorway Link (US)', + tags: { highway: 'motorway_link' }, + geometry: ['line'], + locationSet: { include: ['us'] } + } + }; + + iD.fileFetcher.cache().preset_presets = testPresets; + var presets = iD.presetIndex(); + await presets.ensureLoaded(); + + // Add the US variant to "Recent" presets + var usVariant = presets.item('highway/motorway_link-US'); + presets.setMostRecent(usVariant); + + // Location in US (e.g., New York) + var locUS = [-74.006, 40.7128]; + // Location outside US (e.g., London) + var locUK = [-0.1278, 51.5074]; + + // 1. Verify that in US, the US variant is returned + var defaultsUS = presets.defaults('line', 10, true, locUS); + expect(defaultsUS.collection.some(p => p.id === 'highway/motorway_link-US')).to.be.true; + + // 2. Verify that outside US, the US variant is REPLACED by the base variant + var defaultsUK = presets.defaults('line', 10, true, locUK); + + expect(defaultsUK.collection.some(p => p.id === 'highway/motorway_link-US')).to.be.false; + expect(defaultsUK.collection.some(p => p.id === 'highway/motorway_link')).to.be.true; + }); + + it('removes an invalid regional preset in defaults if no equivalent exists', async () => { + // Define a regional preset with special tags that has NO base equivalent + var testPresets = { + 'highway/special_us_road': { + name: 'Special US Road', + tags: { highway: 'residential', residential: 'special_us' }, + geometry: ['line'], + locationSet: { include: ['us'] } + }, + 'residential': { + name: 'Residential', + tags: { highway: 'residential' }, + geometry: ['line'] + } + }; + + iD.fileFetcher.cache().preset_presets = testPresets; + var presets = iD.presetIndex(); + await presets.ensureLoaded(); + + // Add the US variant to "Recent" presets + var usVariant = presets.item('highway/special_us_road'); + presets.setMostRecent(usVariant); + + // Location outside US + var locUK = [-0.1278, 51.5074]; + + var defaultsUK = presets.defaults('line', 10, true, locUK); + + // 1. The US variant should be removed because it's invalid in UK + expect(defaultsUK.collection.some(p => p.id === 'highway/special_us_road')).to.be.false; + + // 2. No replacement should happen because matchTags({highway: 'residential', residential: 'special_us'}) + // will match 'residential', but 'residential' doesn't have the same specific tags. + expect(defaultsUK.collection.some(p => p.id === 'residential')).to.be.false; + }); + }); });