From c9fd7c941c2d561b3aa319274651b3c0024143e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 23:33:01 +0000 Subject: [PATCH 1/3] Bump axios from 0.30.3 to 0.32.0 Bumps [axios](https://github.com/axios/axios) from 0.30.3 to 0.32.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v0.30.3...v0.32.0) --- updated-dependencies: - dependency-name: axios dependency-version: 0.32.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4493e5494b..d81cee823a 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "@znemz/cesium-navigation": "4.0.0", "ajv": "8.18.0", "assert": "2.0.0", - "axios": "0.30.3", + "axios": "0.32.0", "bootstrap": "3.4.1", "buffer": "6.0.3", "canvas-to-blob": "0.0.0", From f93f55642bc991920f3e15834d531f3e70874031 Mon Sep 17 00:00:00 2001 From: Lorenzo Natali Date: Thu, 18 Jun 2026 15:42:09 +0200 Subject: [PATCH 2/3] Fix axios 0.32.0 compatibility with axios-mock-adapter and test assertions - postInstall.js: patch axios-mock-adapter handle_request.js to use optional chaining on config.headers.constructor, which is null-prototype in axios 0.32.0 (fixes TypeError crash in 373 tests) - RuleService tests: spread config.params before toEqual comparison to convert null-prototype object to plain object (fixes 7 test failures) - RuleService tests: add .catch(e => done(e)) to tests missing it to surface failures as errors instead of silent timeouts Co-Authored-By: Claude Sonnet 4.6 --- utility/build/postInstall.js | 17 ++++++++++++++++- .../api/geofence/__tests__/RuleService-test.js | 16 ++++++++-------- .../geofence/__tests__/RuleService-test.js | 16 ++++++++-------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/utility/build/postInstall.js b/utility/build/postInstall.js index d81d34ea7b..ce3ea54f3c 100644 --- a/utility/build/postInstall.js +++ b/utility/build/postInstall.js @@ -20,6 +20,20 @@ const nodeModules = [ } ]; +// Patch for axios-mock-adapter to support null-prototype headers introduced in axios 0.32.0. +// Remove when https://github.com/ctimmerm/axios-mock-adapter/issues/415 is fixed and released. +function patchAxiosMockAdapter(nodeModulesPath) { + const filePath = path.resolve(nodeModulesPath, 'axios-mock-adapter/src/handle_request.js'); + if (!fs.existsSync(filePath)) return; + const original = 'config.headers.constructor.name === "AxiosHeaders"'; + const patched = 'config.headers.constructor?.name === "AxiosHeaders"'; + const content = fs.readFileSync(filePath, 'utf8'); + if (content.includes(original)) { + console.log('* patching axios-mock-adapter handle_request.js (null-prototype compat)'); + fs.writeFileSync(filePath, content.replace(original, patched), 'utf8'); + } +} + function removeModules(nodeModulesPath) { const removeModulesList = [ 'leaflet-simple-graticule/node_modules' @@ -45,6 +59,7 @@ function removeModules(nodeModulesPath) { nodeModules.forEach((nodeModule) => { if (fs.existsSync(nodeModule.path) && nodeModule.valid) { console.log('remove in node_modules path', nodeModule.path); - removeModules(nodeModule.path) + removeModules(nodeModule.path); + patchAxiosMockAdapter(nodeModule.path); } }); diff --git a/web/client/api/geofence/__tests__/RuleService-test.js b/web/client/api/geofence/__tests__/RuleService-test.js index 40366baaac..90f99b6d1c 100644 --- a/web/client/api/geofence/__tests__/RuleService-test.js +++ b/web/client/api/geofence/__tests__/RuleService-test.js @@ -45,7 +45,7 @@ describe('RuleService API for GeoFence StandAlone', () => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules/count`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual(EXPECTED_PARAMS); + expect({...config.params}).toEqual(EXPECTED_PARAMS); return [200, '2']; }); RuleService.getRulesCount(PARAMS) @@ -61,7 +61,7 @@ describe('RuleService API for GeoFence StandAlone', () => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules/count`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual(EXPECTED_PARAMS); + expect({...config.params}).toEqual(EXPECTED_PARAMS); return [200, "2"]; }); RuleService.getRulesCount(PARAMS) @@ -77,7 +77,7 @@ describe('RuleService API for GeoFence StandAlone', () => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual({...EXPECTED_PARAMS, page: 1, entries: 10}); + expect({...config.params}).toEqual({...EXPECTED_PARAMS, page: 1, entries: 10}); return [200, RULES]; }); RuleService.loadRules(1, PARAMS, 10).then(v => { @@ -87,7 +87,7 @@ describe('RuleService API for GeoFence StandAlone', () => { expect(v.rules[0].grant).toBe("ALLOW"); expect(v.rules[2].rolename).toBe("TEST_ROLE"); done(); - }); + }).catch(e => done(e)); }); it('loadRules with [field]Any param with/without value for its [field]', (done) => { const PARAMS = { roleName: "ADMIN", workspaceAny: true, service: "WFS", serviceAny: false }; @@ -95,7 +95,7 @@ describe('RuleService API for GeoFence StandAlone', () => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual({...EXPECTED_PARAMS, page: 1, entries: 10}); + expect({...config.params}).toEqual({...EXPECTED_PARAMS, page: 1, entries: 10}); return [200, RULES]; }); RuleService.loadRules(1, PARAMS, 10).then(v => { @@ -105,18 +105,18 @@ describe('RuleService API for GeoFence StandAlone', () => { expect(v.rules[0].grant).toBe("ALLOW"); expect(v.rules[0].workspace).toBe("WORKSPACE"); done(); - }); + }).catch(e => done(e)); }); it('moveRules', (done) => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules/move`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual({ targetPriority: 1, rulesIds: '1,2' }); + expect({...config.params}).toEqual({ targetPriority: 1, rulesIds: '1,2' }); return [200, RULES]; }); RuleService.moveRules(1, [{id: 1 }, { id: 2 }]).then(() => { done(); - }); + }).catch(e => done(e)); }); it('addRule', (done) => { mockAxios.onPost().reply(config => { diff --git a/web/client/api/geoserver/geofence/__tests__/RuleService-test.js b/web/client/api/geoserver/geofence/__tests__/RuleService-test.js index 061227cbbf..5da795490c 100644 --- a/web/client/api/geoserver/geofence/__tests__/RuleService-test.js +++ b/web/client/api/geoserver/geofence/__tests__/RuleService-test.js @@ -41,7 +41,7 @@ describe('RuleService API for GeoFence StandAlone', () => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules/count`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual(EXPECTED_PARAMS); + expect({...config.params}).toEqual(EXPECTED_PARAMS); return [200, RULES]; }); RuleService.getRulesCount(PARAMS) @@ -57,7 +57,7 @@ describe('RuleService API for GeoFence StandAlone', () => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules/count`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual(EXPECTED_PARAMS); + expect({...config.params}).toEqual(EXPECTED_PARAMS); return [200, RULES]; }); RuleService.getRulesCount(PARAMS) @@ -74,7 +74,7 @@ describe('RuleService API for GeoFence StandAlone', () => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual({...EXPECTED_PARAMS, page: 1, entries: 10}); + expect({...config.params}).toEqual({...EXPECTED_PARAMS, page: 1, entries: 10}); return [200, RULES]; }); RuleService.loadRules(1, PARAMS, 10).then(v => { @@ -84,7 +84,7 @@ describe('RuleService API for GeoFence StandAlone', () => { expect(v.rules[0].grant).toBe("ALLOW"); expect(v.rules[0].rolename).toBe("ADMIN"); done(); - }); + }).catch(e => done(e)); }); it('loadRules with [field]Any param with/without value for its [field]', (done) => { const PARAMS = { roleName: "ADMIN", workspaceAny: true, service: "WFS", serviceAny: false }; @@ -92,7 +92,7 @@ describe('RuleService API for GeoFence StandAlone', () => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual({...EXPECTED_PARAMS, page: 1, entries: 10}); + expect({...config.params}).toEqual({...EXPECTED_PARAMS, page: 1, entries: 10}); return [200, RULES]; }); RuleService.loadRules(1, PARAMS, 10).then(v => { @@ -102,20 +102,20 @@ describe('RuleService API for GeoFence StandAlone', () => { expect(v.rules[0].grant).toBe("ALLOW"); expect(v.rules[0].rolename).toBe("ADMIN"); done(); - }); + }).catch(e => done(e)); }); it('moveRules', (done) => { mockAxios.onGet().reply(config => { expect(config.url).toBe(`/rules/move`); expect(config.baseURL).toBe(`${BASE_URL}`); - expect(config.params).toEqual({ targetPriority: 1, rulesIds: '1,2' }); + expect({...config.params}).toEqual({ targetPriority: 1, rulesIds: '1,2' }); return [200, RULES]; }); RuleService.moveRules(1, [{id: 1 }, { id: 2 }]).then(v => { expect(v.rules).toExist(); expect(v.rules.length).toBe(2); done(); - }); + }).catch(e => done(e)); }); it('addRule', (done) => { mockAxios.onPost().reply(config => { From 315f84edf7437eb488d2fc88a3bc85520ddcdbae Mon Sep 17 00:00:00 2001 From: Lorenzo Natali Date: Thu, 18 Jun 2026 15:48:31 +0200 Subject: [PATCH 3/3] Fix axios 0.32.0 null-prototype params in GeoNode, GeoStore, ResourcesCatalog tests Spread config.params/{data.params} before toEqual to convert null-prototype objects (introduced by axios 0.32.0) to plain objects for expect@1.20.1 compatibility. Co-Authored-By: Claude Sonnet 4.6 --- web/client/api/__tests__/GeoNode-test.js | 4 ++-- web/client/api/__tests__/GeoStoreDAO-test.jsx | 2 +- web/client/api/__tests__/ResourcesCatalog-test.js | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/web/client/api/__tests__/GeoNode-test.js b/web/client/api/__tests__/GeoNode-test.js index 13e9b5ad37..32c49c4c44 100644 --- a/web/client/api/__tests__/GeoNode-test.js +++ b/web/client/api/__tests__/GeoNode-test.js @@ -69,7 +69,7 @@ describe('Test correctness of the GeoNode APIs (mock axios)', () => { mockAxios.onGet().reply((config) => { try { expect(config.url).toBe('https://example.com/api/v2/resources'); - expect(config.params).toEqual({ + expect({...config.params}).toEqual({ 'filter{metadata_only}': false, include: [ 'advertised', @@ -135,7 +135,7 @@ describe('Test correctness of the GeoNode APIs (mock axios)', () => { mockAxios.onGet().reply((config) => { try { expect(config.url).toBe('https://example.com/api/v2/resources'); - expect(config.params).toEqual({ + expect({...config.params}).toEqual({ 'filter{metadata_only}': false, include: [ 'advertised', diff --git a/web/client/api/__tests__/GeoStoreDAO-test.jsx b/web/client/api/__tests__/GeoStoreDAO-test.jsx index 28208a7e01..cc3a9c6bcb 100644 --- a/web/client/api/__tests__/GeoStoreDAO-test.jsx +++ b/web/client/api/__tests__/GeoStoreDAO-test.jsx @@ -428,7 +428,7 @@ describe('Test correctness of the GeoStore APIs', () => { try { expect(data.baseURL).toBe('/rest/geostore/'); expect(data.url).toBe('/resources/tag'); - expect(data.params).toEqual({ nameLike: '%Search%' }); + expect({...data.params}).toEqual({ nameLike: '%Search%' }); } catch (e) { done(e); } diff --git a/web/client/api/__tests__/ResourcesCatalog-test.js b/web/client/api/__tests__/ResourcesCatalog-test.js index 984cf25266..41deaf6d2b 100644 --- a/web/client/api/__tests__/ResourcesCatalog-test.js +++ b/web/client/api/__tests__/ResourcesCatalog-test.js @@ -31,7 +31,7 @@ describe('ResourceCatalog api', () => { mockAxios.onPost().replyOnce((config) => { try { expect(config.url).toBe('/extjs/search/list'); - expect(config.params).toEqual({ includeAttributes: true, includeTags: true, start: 0, limit: 12, sortBy: 'name', sortOrder: 'asc' }); + expect({...config.params}).toEqual({ includeAttributes: true, includeTags: true, start: 0, limit: 12, sortBy: 'name', sortOrder: 'asc' }); expect(config.testConfig).toBe('test'); let json; xml2js.parseString(config.data, { explicitArray: false }, (ignore, result) => { @@ -79,7 +79,7 @@ describe('ResourceCatalog api', () => { mockAxios.onPost().replyOnce((config) => { try { expect(config.url).toBe('/extjs/search/list'); - expect(config.params).toEqual({ includeAttributes: true, includeTags: true, start: 0, limit: 12, sortBy: 'name', sortOrder: 'asc' }); + expect({...config.params}).toEqual({ includeAttributes: true, includeTags: true, start: 0, limit: 12, sortBy: 'name', sortOrder: 'asc' }); expect(config.testConfig).toBe('test'); let json; xml2js.parseString(config.data, { explicitArray: false }, (ignore, result) => { @@ -127,7 +127,7 @@ describe('ResourceCatalog api', () => { mockAxios.onPost().replyOnce((config) => { try { expect(config.url).toBe('/extjs/search/list'); - expect(config.params).toEqual({ includeAttributes: true, includeTags: true, start: 0, limit: 12, sortBy: 'name', sortOrder: 'asc' }); + expect({...config.params}).toEqual({ includeAttributes: true, includeTags: true, start: 0, limit: 12, sortBy: 'name', sortOrder: 'asc' }); expect(config.testConfig).toBe('test'); let json; xml2js.parseString(config.data, { explicitArray: false }, (ignore, result) => { @@ -179,7 +179,7 @@ describe('ResourceCatalog api', () => { mockAxios.onPost().replyOnce((config) => { try { expect(config.url).toBe('/extjs/search/list'); - expect(config.params).toEqual({ includeAttributes: true, includeTags: true, start: 24, limit: 24, sortBy: 'name', sortOrder: 'asc', favoritesOnly: true }); + expect({...config.params}).toEqual({ includeAttributes: true, includeTags: true, start: 24, limit: 24, sortBy: 'name', sortOrder: 'asc', favoritesOnly: true }); let json; xml2js.parseString(config.data, { explicitArray: false }, (ignore, result) => { json = result; @@ -277,7 +277,7 @@ describe('ResourceCatalog api', () => { mockAxios.onPost().replyOnce((config) => { try { expect(config.url).toBe('/extjs/search/list'); - expect(config.params).toEqual({ includeAttributes: true, includeTags: true, start: 24, limit: 24, sortBy: 'name', sortOrder: 'asc', favoritesOnly: true }); + expect({...config.params}).toEqual({ includeAttributes: true, includeTags: true, start: 24, limit: 24, sortBy: 'name', sortOrder: 'asc', favoritesOnly: true }); let json; xml2js.parseString(config.data, { explicitArray: false }, (ignore, result) => { json = result; @@ -382,7 +382,7 @@ describe('ResourceCatalog api', () => { mockAxios.onPost().replyOnce((config) => { try { expect(config.url).toBe('/extjs/search/list'); - expect(config.params).toEqual({ includeAttributes: true, includeTags: true, start: 24, limit: 24, sortBy: 'name', sortOrder: 'asc', favoritesOnly: true }); + expect({...config.params}).toEqual({ includeAttributes: true, includeTags: true, start: 24, limit: 24, sortBy: 'name', sortOrder: 'asc', favoritesOnly: true }); let json; xml2js.parseString(config.data, { explicitArray: false }, (ignore, result) => { json = result; @@ -492,7 +492,7 @@ describe('ResourceCatalog api', () => { mockAxios.onPost().replyOnce((config) => { try { expect(config.url).toBe('/extjs/search/list'); - expect(config.params).toEqual({ includeAttributes: true, includeTags: true, start: 0, limit: 12, sortBy: 'name', sortOrder: 'asc' }); + expect({...config.params}).toEqual({ includeAttributes: true, includeTags: true, start: 0, limit: 12, sortBy: 'name', sortOrder: 'asc' }); } catch (e) { done(e); }