From d86313fe52c49ab114ff3dba318d97bd02425a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Ronzon?= Date: Sun, 28 Jun 2026 12:50:06 -0600 Subject: [PATCH 1/2] fix(search): resolve null entrances in cave search results - Handle both Waterline objects and plain IDs in toSimpleCave converter - Add regression tests for entrance ID extraction --- api/services/mapping/converters.js | 2 +- .../integration/1_services/Converters.test.js | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/api/services/mapping/converters.js b/api/services/mapping/converters.js index 2e8e867bb..9b7ec13d0 100644 --- a/api/services/mapping/converters.js +++ b/api/services/mapping/converters.js @@ -79,7 +79,7 @@ const c = { temperature: source.temperature, isDiving: source.isDiving, nbEntrances: source.nbEntrances ?? source.entrances?.length ?? 0, - entrances: source.entrances?.map((e) => e.id), + entrances: source.entrances?.map((e) => e?.id ?? e), }), toCaver: (source, meta) => { diff --git a/test/integration/1_services/Converters.test.js b/test/integration/1_services/Converters.test.js index 3895b7068..f0b24cc5d 100644 --- a/test/integration/1_services/Converters.test.js +++ b/test/integration/1_services/Converters.test.js @@ -204,6 +204,44 @@ describe('Converters Service', () => { const result = converters.toSimpleCave(source); should(result.exploringOrganizations).be.undefined(); }); + + it('should extract entrance IDs from Waterline objects', () => { + const source = { + id: 1, + entrances: [ + { id: 5, name: 'Entrance A' }, + { id: 6, name: 'Entrance B' }, + ], + }; + const result = converters.toSimpleCave(source); + should(result.entrances).deepEqual([5, 6]); + }); + + it('should pass through plain entrance IDs (Typesense format)', () => { + const source = { + id: 1, + nbEntrances: 3, + entrances: [20, 21, 25877], + }; + const result = converters.toSimpleCave(source); + should(result.entrances).deepEqual([20, 21, 25877]); + }); + + it('should pass through string entrance IDs', () => { + const source = { + id: 1, + nbEntrances: 2, + entrances: ['20', '21'], + }; + const result = converters.toSimpleCave(source); + should(result.entrances).deepEqual(['20', '21']); + }); + + it('should return undefined entrances when field is absent', () => { + const source = { id: 1, nbEntrances: 0 }; + const result = converters.toSimpleCave(source); + should(result.entrances).be.undefined(); + }); }); describe('toDocument()', () => { From 6c950a246216af4894388f961392a46b13981e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Ronzon?= Date: Sun, 28 Jun 2026 16:57:38 -0600 Subject: [PATCH 2/2] fix(search): filter null entries from cave entrances mapping - Add .filter() to remove null/undefined from toSimpleCave entrances - Add test for null-in-array edge case - Add test for empty entrances array --- api/services/mapping/converters.js | 4 +++- test/integration/1_services/Converters.test.js | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/api/services/mapping/converters.js b/api/services/mapping/converters.js index 9b7ec13d0..2026f422e 100644 --- a/api/services/mapping/converters.js +++ b/api/services/mapping/converters.js @@ -79,7 +79,9 @@ const c = { temperature: source.temperature, isDiving: source.isDiving, nbEntrances: source.nbEntrances ?? source.entrances?.length ?? 0, - entrances: source.entrances?.map((e) => e?.id ?? e), + entrances: source.entrances + ?.map((e) => e?.id ?? e) + .filter((e) => e != null), }), toCaver: (source, meta) => { diff --git a/test/integration/1_services/Converters.test.js b/test/integration/1_services/Converters.test.js index f0b24cc5d..472813b06 100644 --- a/test/integration/1_services/Converters.test.js +++ b/test/integration/1_services/Converters.test.js @@ -237,6 +237,21 @@ describe('Converters Service', () => { should(result.entrances).deepEqual(['20', '21']); }); + it('should filter out null entries from entrances array', () => { + const source = { + id: 1, + entrances: [{ id: 5 }, null, { id: 6 }, undefined], + }; + const result = converters.toSimpleCave(source); + should(result.entrances).deepEqual([5, 6]); + }); + + it('should return an empty array when entrances is empty', () => { + const source = { id: 1, entrances: [] }; + const result = converters.toSimpleCave(source); + should(result.entrances).deepEqual([]); + }); + it('should return undefined entrances when field is absent', () => { const source = { id: 1, nbEntrances: 0 }; const result = converters.toSimpleCave(source);