From 8cdc54d2dc747e0a3d19e8aeb7c234ad794e968a Mon Sep 17 00:00:00 2001 From: Suren Date: Fri, 26 Jun 2026 18:01:34 +0530 Subject: [PATCH 1/3] #12553: Fix - WMC export fails when maxExtent is undefined --- web/client/utils/ogc/WMC/index.js | 7 +++---- web/client/utils/ogc/__tests__/WMC-test.js | 12 ++++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/web/client/utils/ogc/WMC/index.js b/web/client/utils/ogc/WMC/index.js index 37746ec566..4e1da57a37 100644 --- a/web/client/utils/ogc/WMC/index.js +++ b/web/client/utils/ogc/WMC/index.js @@ -7,7 +7,7 @@ */ import { Parser } from 'xml2js'; -import { keys, values, get, head, mapValues, uniqWith, findIndex, pick, has, toPairs, castArray } from 'lodash'; +import { keys, values, get, head, mapValues, uniqWith, findIndex, pick, has, toPairs, castArray, isEmpty } from 'lodash'; import { v1 as uuidv1 } from 'uuid'; import { @@ -391,8 +391,7 @@ export const toWMC = ( }) }; }; - - const olExtensionsGeneral = assignNamespace([{ + const olExtensionsGeneral = isEmpty(maxExtent) ? [] : assignNamespace([{ name: 'maxExtent', attributes: objectToAttributes({ minx: maxExtent[0], @@ -629,7 +628,7 @@ export const toWMC = ( attributes: objectToAttributes(isValidBboxObject(bbox) ? { ...bbox.bounds, SRS: bbox.crs - } : { + } : isEmpty(maxExtent) ? {} : { minx: maxExtent[0], miny: maxExtent[1], maxx: maxExtent[2], diff --git a/web/client/utils/ogc/__tests__/WMC-test.js b/web/client/utils/ogc/__tests__/WMC-test.js index ef2aec0bed..1a9bd08772 100644 --- a/web/client/utils/ogc/__tests__/WMC-test.js +++ b/web/client/utils/ogc/__tests__/WMC-test.js @@ -344,4 +344,16 @@ describe('WMC tests', () => { expect({text: exportedLine, line: i + 1}).toEqual({text: contextLine, line: i + 1})); }) ); + it('toWMC with empty maxExtent should not fail', () => { + // Only for test coverage. + // BoundingBox cannot be empty as it's derived from the map bbox (preferred) or maxExtent, + // with bbox always available in the map state + Promise.all([ + axios.get('base/web/client/test-resources/wmc/config.json') + ]).then(([{data: config}]) => { + const _config = omit(config, "map.maxExtent"); + const exportedLines = toWMC(_config, {}).split('\n').map(r => r.trim()).filter(e => e); + expect(exportedLines.some(line => [""].includes(line))).toBeTruthy(); + }); + }); }); From 9b13b014ea65df5285f1ba745b2a5581a6deacfe Mon Sep 17 00:00:00 2001 From: Suren Date: Mon, 29 Jun 2026 11:05:51 +0530 Subject: [PATCH 2/3] remove test --- web/client/utils/ogc/__tests__/WMC-test.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/web/client/utils/ogc/__tests__/WMC-test.js b/web/client/utils/ogc/__tests__/WMC-test.js index 1a9bd08772..ef2aec0bed 100644 --- a/web/client/utils/ogc/__tests__/WMC-test.js +++ b/web/client/utils/ogc/__tests__/WMC-test.js @@ -344,16 +344,4 @@ describe('WMC tests', () => { expect({text: exportedLine, line: i + 1}).toEqual({text: contextLine, line: i + 1})); }) ); - it('toWMC with empty maxExtent should not fail', () => { - // Only for test coverage. - // BoundingBox cannot be empty as it's derived from the map bbox (preferred) or maxExtent, - // with bbox always available in the map state - Promise.all([ - axios.get('base/web/client/test-resources/wmc/config.json') - ]).then(([{data: config}]) => { - const _config = omit(config, "map.maxExtent"); - const exportedLines = toWMC(_config, {}).split('\n').map(r => r.trim()).filter(e => e); - expect(exportedLines.some(line => [""].includes(line))).toBeTruthy(); - }); - }); }); From e873bcdf87af0ecb533f1706ce7e25d321359ea4 Mon Sep 17 00:00:00 2001 From: Suren Date: Mon, 29 Jun 2026 13:41:24 +0530 Subject: [PATCH 3/3] update handler --- web/client/utils/ogc/WMC/index.js | 20 +++++++++++--------- web/client/utils/ogc/__tests__/WMC-test.js | 13 +++++++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/web/client/utils/ogc/WMC/index.js b/web/client/utils/ogc/WMC/index.js index 4e1da57a37..c638e9684a 100644 --- a/web/client/utils/ogc/WMC/index.js +++ b/web/client/utils/ogc/WMC/index.js @@ -391,15 +391,17 @@ export const toWMC = ( }) }; }; - const olExtensionsGeneral = isEmpty(maxExtent) ? [] : assignNamespace([{ - name: 'maxExtent', - attributes: objectToAttributes({ - minx: maxExtent[0], - miny: maxExtent[1], - maxx: maxExtent[2], - maxy: maxExtent[3] - }) - }], namespaces.ol); + const olExtensionsGeneral = isEmpty(maxExtent) + ? castArray(makeMaxExtentFromBbox(bbox)) + : assignNamespace([{ + name: 'maxExtent', + attributes: objectToAttributes({ + minx: maxExtent[0], + miny: maxExtent[1], + maxx: maxExtent[2], + maxy: maxExtent[3] + }) + }], namespaces.ol); const msExtensionsGeneral = assignNamespace([groups.length > 0 ? { name: 'GroupList', children: groups.map(group => ({ diff --git a/web/client/utils/ogc/__tests__/WMC-test.js b/web/client/utils/ogc/__tests__/WMC-test.js index ef2aec0bed..42955214b1 100644 --- a/web/client/utils/ogc/__tests__/WMC-test.js +++ b/web/client/utils/ogc/__tests__/WMC-test.js @@ -344,4 +344,17 @@ describe('WMC tests', () => { expect({text: exportedLine, line: i + 1}).toEqual({text: contextLine, line: i + 1})); }) ); + it('toWMC with empty maxExtent should not fail', () => { + Promise.all([ + axios.get('base/web/client/test-resources/wmc/config.json'), + axios.get('base/web/client/test-resources/wmc/exported-context.wmc') + ]).then(([{data: config}, {data: context}]) => { + const _config = omit(config, "map.maxExtent"); // remove mapExtent + const exportedLines = toWMC(_config, {}).split('\n').map(r => r.trim()).filter(e => e); + const contextLines = context.split('\n').map(r => r.trim()).filter(e => e); + + zip(exportedLines, contextLines).forEach(([exportedLine, contextLine], i) => + expect({text: exportedLine, line: i + 1}).toEqual({text: contextLine, line: i + 1})); + }); + }); });