From b0edb1d7e2dc552578f72740c60eb0cfa046efe2 Mon Sep 17 00:00:00 2001 From: Ron Israeli Date: Mon, 25 May 2026 00:19:29 +0300 Subject: [PATCH 1/5] feat(sync): code review(MAPCO-10530) --- .../layersClient/geometryParser.ts | 1 + .../externalClients/geometryParser.spec.ts | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/externalClients/layersClient/geometryParser.ts b/src/externalClients/layersClient/geometryParser.ts index e9c6637..a8ddfbe 100644 --- a/src/externalClients/layersClient/geometryParser.ts +++ b/src/externalClients/layersClient/geometryParser.ts @@ -37,6 +37,7 @@ export function geographyToGeoJSON(geography: RawGeography): Geometry { return lineString(coords.map(toPosition)).geometry as LineString; case 'POLYGON': + case 'AREA': if (coords.length < 4) { throw new Error(`Polygon requires >=4 coordinates (closed ring), got ${coords.length}`); } diff --git a/tests/unit/externalClients/geometryParser.spec.ts b/tests/unit/externalClients/geometryParser.spec.ts index be9343f..a02937d 100644 --- a/tests/unit/externalClients/geometryParser.spec.ts +++ b/tests/unit/externalClients/geometryParser.spec.ts @@ -80,6 +80,27 @@ describe('geographyToGeoJSON', () => { ]; expect(() => geographyToGeoJSON(geo('POLYGON', ring))).toThrow(/Polygon requires >=4/); }); + + it('accepts AREA alias as Polygon', () => { + const ring = [ + { latitude: 0, longitude: 0 }, + { latitude: 0, longitude: 1 }, + { latitude: 1, longitude: 1 }, + { latitude: 0, longitude: 0 }, + ]; + const result = geographyToGeoJSON(geo('AREA', ring)); + expect(result).toEqual({ + type: 'Polygon', + coordinates: [ + [ + [0, 0], + [1, 0], + [1, 1], + [0, 0], + ], + ], + }); + }); }); describe('error cases', () => { From 3e6e292c306eb5384c2efd020594760cfc17720a Mon Sep 17 00:00:00 2001 From: Ron Israeli Date: Mon, 25 May 2026 17:03:59 +0300 Subject: [PATCH 2/5] feat(sync): code review(MAPCO-10530) --- .../layersClient/geometryParser.ts | 67 ++++++++++--------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/externalClients/layersClient/geometryParser.ts b/src/externalClients/layersClient/geometryParser.ts index a8ddfbe..cf5452b 100644 --- a/src/externalClients/layersClient/geometryParser.ts +++ b/src/externalClients/layersClient/geometryParser.ts @@ -18,35 +18,42 @@ function toPosition(c: RawCoordinate): Position { } export function geographyToGeoJSON(geography: RawGeography): Geometry { - const kind = geography.graphicsObjectKind.value.toUpperCase(); - const coords = geography.coordinates; - - if (coords.length === 0) { - throw new Error(`Empty coordinates for graphicsObjectKind=${kind}`); - } - - switch (kind) { - case 'POINT': - return point(toPosition(coords[0]!)).geometry as Point; - - case 'LINE': - case 'LINESTRING': - if (coords.length < 2) { - throw new Error(`LineString requires >=2 coordinates, got ${coords.length}`); - } - return lineString(coords.map(toPosition)).geometry as LineString; - - case 'POLYGON': - case 'AREA': - if (coords.length < 4) { - throw new Error(`Polygon requires >=4 coordinates (closed ring), got ${coords.length}`); - } - return polygon([coords.map(toPosition)]).geometry as Polygon; - - default: - if (MULTI_KINDS.has(kind)) { - throw new Error(`Unsupported graphicsObjectKind=${kind}: MULTI* encoding not yet documented`); - } - throw new Error(`Unknown graphicsObjectKind=${kind}`); + try { + const kind = geography.graphicsObjectKind.value.toUpperCase(); + const coords = geography.coordinates; + + if (coords.length === 0) { + throw new Error(`Empty coordinates for graphicsObjectKind=${kind}`); + } + + switch (kind) { + case 'POINT': + return point(toPosition(coords[0]!)).geometry as Point; + + case 'LINE': + case 'LINESTRING': + if (coords.length < 2) { + throw new Error(`LineString requires >=2 coordinates, got ${coords.length}`); + } + return lineString(coords.map(toPosition)).geometry as LineString; + + case 'POLYGON': + case 'AREA': + if (coords.length < 4) { + throw new Error(`Polygon requires >=4 coordinates (closed ring), got ${coords.length}`); + } + return polygon([coords.map(toPosition)]).geometry as Polygon; + + default: + if (MULTI_KINDS.has(kind)) { + console.error('geographyToGeoJSON unsupported MULTI* kind:', JSON.stringify(geography)); + throw new Error(`Unsupported graphicsObjectKind=${kind}: MULTI* encoding not yet documented`); + } + console.error('geographyToGeoJSON unknown kind:', JSON.stringify(geography)); + throw new Error(`Unknown graphicsObjectKind=${kind}`); + } + } catch (err) { + console.error('geographyToGeoJSON failed for geography:', JSON.stringify(geography)); + throw err; } } From 46bb6d725e4c552970e16c05a834acc49094e2b4 Mon Sep 17 00:00:00 2001 From: Ron Israeli Date: Mon, 25 May 2026 18:22:51 +0300 Subject: [PATCH 3/5] feat(sync): code review(MAPCO-10530) --- .../layersClient/geometryParser.ts | 9 +++--- .../layersClient/layersClient.ts | 9 +++--- src/handler/layerSyncHandler.ts | 2 +- .../externalClients/geometryParser.spec.ts | 30 +++++++++++++------ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/externalClients/layersClient/geometryParser.ts b/src/externalClients/layersClient/geometryParser.ts index cf5452b..eac59a0 100644 --- a/src/externalClients/layersClient/geometryParser.ts +++ b/src/externalClients/layersClient/geometryParser.ts @@ -1,4 +1,5 @@ import { point, lineString, polygon } from '@turf/helpers'; +import type { Logger } from '@map-colonies/js-logger'; import type { Geometry, LineString, Point, Polygon, Position } from 'geojson'; export interface RawCoordinate { @@ -17,7 +18,7 @@ function toPosition(c: RawCoordinate): Position { return [c.longitude, c.latitude]; } -export function geographyToGeoJSON(geography: RawGeography): Geometry { +export function geographyToGeoJSON(logger: Logger, geography: RawGeography): Geometry { try { const kind = geography.graphicsObjectKind.value.toUpperCase(); const coords = geography.coordinates; @@ -46,14 +47,14 @@ export function geographyToGeoJSON(geography: RawGeography): Geometry { default: if (MULTI_KINDS.has(kind)) { - console.error('geographyToGeoJSON unsupported MULTI* kind:', JSON.stringify(geography)); + logger.error({ msg: 'geographyToGeoJSON unsupported MULTI* kind', geography }); throw new Error(`Unsupported graphicsObjectKind=${kind}: MULTI* encoding not yet documented`); } - console.error('geographyToGeoJSON unknown kind:', JSON.stringify(geography)); + logger.error({ msg: 'geographyToGeoJSON unknown kind', geography }); throw new Error(`Unknown graphicsObjectKind=${kind}`); } } catch (err) { - console.error('geographyToGeoJSON failed for geography:', JSON.stringify(geography)); + logger.error({ msg: 'geographyToGeoJSON failed', geography, err }); throw err; } } diff --git a/src/externalClients/layersClient/layersClient.ts b/src/externalClients/layersClient/layersClient.ts index 8512e96..7ab0cf8 100644 --- a/src/externalClients/layersClient/layersClient.ts +++ b/src/externalClients/layersClient/layersClient.ts @@ -1,6 +1,7 @@ import axios from 'axios'; import { trace } from '@opentelemetry/api'; import { asyncCallWithSpan } from '@map-colonies/tracing-utils'; +import type { Logger } from '@map-colonies/js-logger'; import type { LayerObject, ThirdPartyResponse } from '../../types'; import { getSyncConfig } from '../../common/syncConfig'; import { SERVICE_NAME } from '../../common/constants'; @@ -38,10 +39,10 @@ interface GraphQLResponse { const tracer = trace.getTracer(SERVICE_NAME); -function toLayerObject(raw: RawLayerObject): LayerObject { +function toLayerObject(logger: Logger, raw: RawLayerObject): LayerObject { return { id: raw.id, - geom: geographyToGeoJSON(raw.geography), + geom: geographyToGeoJSON(logger, raw.geography), properties: { createdBy: raw.createdBy, creationTime: raw.creationTime, @@ -56,7 +57,7 @@ function toLayerObject(raw: RawLayerObject): LayerObject { }; } -export async function fetchPage(layerName: string, sequence: string): Promise { +export async function fetchPage(logger: Logger, layerName: string, sequence: string): Promise { const config = getSyncConfig(); return asyncCallWithSpan( @@ -84,7 +85,7 @@ export async function fetchPage(layerName: string, sequence: string): Promise !o.deleted).map(toLayerObject); + const objects = rawObjects.filter((o) => !o.deleted).map((raw) => toLayerObject(logger, raw)); const { sequence: nextSequence, deletedEntitiesCount, fetchedEntitiesCount, deletedEntitiesIds } = json.extensions; return { diff --git a/src/handler/layerSyncHandler.ts b/src/handler/layerSyncHandler.ts index 4747d3b..3f48b4d 100644 --- a/src/handler/layerSyncHandler.ts +++ b/src/handler/layerSyncHandler.ts @@ -19,7 +19,7 @@ export async function fetchAndSyncLayerPage(logger: Logger, entry: ScheduleEntry try { logger.info(`Fetching page for layer "${entry.layerName}" - status: ${state.status}, lastSequence: ${state.lastSequence}`); - const response = await layerClient.fetchPage(entry.layerName, state.lastSequence); + const response = await layerClient.fetchPage(logger, entry.layerName, state.lastSequence); logger.info(`Received ${response.fetchedCount} objects, ${response.deletedCount} deleted for layer "${entry.layerName}"`); diff --git a/tests/unit/externalClients/geometryParser.spec.ts b/tests/unit/externalClients/geometryParser.spec.ts index a02937d..fb0ca5b 100644 --- a/tests/unit/externalClients/geometryParser.spec.ts +++ b/tests/unit/externalClients/geometryParser.spec.ts @@ -1,6 +1,16 @@ import { describe, expect, it } from 'vitest'; +import type { Logger } from '@map-colonies/js-logger'; import { geographyToGeoJSON, type RawGeography } from '@src/externalClients/layersClient/geometryParser'; +const logger = { + error: () => undefined, + info: () => undefined, + debug: () => undefined, + warn: () => undefined, + fatal: () => undefined, + trace: () => undefined, +} as unknown as Logger; + function geo(kind: string, coords: { latitude: number; longitude: number }[]): RawGeography { return { coordinates: coords, graphicsObjectKind: { value: kind } }; } @@ -8,12 +18,12 @@ function geo(kind: string, coords: { latitude: number; longitude: number }[]): R describe('geographyToGeoJSON', () => { describe('POINT', () => { it('maps single coordinate to Point with [lng, lat] order', () => { - const result = geographyToGeoJSON(geo('POINT', [{ latitude: 32.0853, longitude: 34.7818 }])); + const result = geographyToGeoJSON(logger, geo('POINT', [{ latitude: 32.0853, longitude: 34.7818 }])); expect(result).toEqual({ type: 'Point', coordinates: [34.7818, 32.0853] }); }); it('accepts lowercase kind', () => { - const result = geographyToGeoJSON(geo('point', [{ latitude: 1, longitude: 2 }])); + const result = geographyToGeoJSON(logger, geo('point', [{ latitude: 1, longitude: 2 }])); expect(result).toEqual({ type: 'Point', coordinates: [2, 1] }); }); }); @@ -21,6 +31,7 @@ describe('geographyToGeoJSON', () => { describe('LINE / LINESTRING', () => { it('maps 2+ coords to LineString in [lng, lat] order', () => { const result = geographyToGeoJSON( + logger, geo('LINE', [ { latitude: 32.7453754, longitude: 35.1867382 }, { latitude: 32.7454701, longitude: 35.1854494 }, @@ -37,6 +48,7 @@ describe('geographyToGeoJSON', () => { it('accepts LINESTRING alias', () => { const result = geographyToGeoJSON( + logger, geo('LINESTRING', [ { latitude: 1, longitude: 2 }, { latitude: 3, longitude: 4 }, @@ -46,7 +58,7 @@ describe('geographyToGeoJSON', () => { }); it('throws when fewer than 2 coords', () => { - expect(() => geographyToGeoJSON(geo('LINE', [{ latitude: 1, longitude: 2 }]))).toThrow(/LineString requires >=2/); + expect(() => geographyToGeoJSON(logger, geo('LINE', [{ latitude: 1, longitude: 2 }]))).toThrow(/LineString requires >=2/); }); }); @@ -58,7 +70,7 @@ describe('geographyToGeoJSON', () => { { latitude: 1, longitude: 1 }, { latitude: 0, longitude: 0 }, ]; - const result = geographyToGeoJSON(geo('POLYGON', ring)); + const result = geographyToGeoJSON(logger, geo('POLYGON', ring)); expect(result).toEqual({ type: 'Polygon', coordinates: [ @@ -78,7 +90,7 @@ describe('geographyToGeoJSON', () => { { latitude: 1, longitude: 1 }, { latitude: 0, longitude: 0 }, ]; - expect(() => geographyToGeoJSON(geo('POLYGON', ring))).toThrow(/Polygon requires >=4/); + expect(() => geographyToGeoJSON(logger, geo('POLYGON', ring))).toThrow(/Polygon requires >=4/); }); it('accepts AREA alias as Polygon', () => { @@ -88,7 +100,7 @@ describe('geographyToGeoJSON', () => { { latitude: 1, longitude: 1 }, { latitude: 0, longitude: 0 }, ]; - const result = geographyToGeoJSON(geo('AREA', ring)); + const result = geographyToGeoJSON(logger, geo('AREA', ring)); expect(result).toEqual({ type: 'Polygon', coordinates: [ @@ -105,15 +117,15 @@ describe('geographyToGeoJSON', () => { describe('error cases', () => { it('throws on empty coordinates', () => { - expect(() => geographyToGeoJSON(geo('POINT', []))).toThrow(/Empty coordinates/); + expect(() => geographyToGeoJSON(logger, geo('POINT', []))).toThrow(/Empty coordinates/); }); it.each(['MULTIPOINT', 'MULTILINE', 'MULTILINESTRING', 'MULTIPOLYGON'])('throws unsupported for %s', (kind) => { - expect(() => geographyToGeoJSON(geo(kind, [{ latitude: 1, longitude: 2 }]))).toThrow(/Unsupported graphicsObjectKind/); + expect(() => geographyToGeoJSON(logger, geo(kind, [{ latitude: 1, longitude: 2 }]))).toThrow(/Unsupported graphicsObjectKind/); }); it('throws on unknown kind', () => { - expect(() => geographyToGeoJSON(geo('TRIANGLE', [{ latitude: 1, longitude: 2 }]))).toThrow(/Unknown graphicsObjectKind=TRIANGLE/); + expect(() => geographyToGeoJSON(logger, geo('TRIANGLE', [{ latitude: 1, longitude: 2 }]))).toThrow(/Unknown graphicsObjectKind=TRIANGLE/); }); }); }); From e4601e527c644d3efcfe530c952c4a3e0b1ff773 Mon Sep 17 00:00:00 2001 From: Ron Israeli Date: Mon, 25 May 2026 18:25:22 +0300 Subject: [PATCH 4/5] feat(sync): code review(MAPCO-10524) --- .../layersClient/geometryParser.ts | 70 ++++++++----------- .../layersClient/layersClient.ts | 9 ++- .../externalClients/geometryParser.spec.ts | 30 +++----- 3 files changed, 48 insertions(+), 61 deletions(-) diff --git a/src/externalClients/layersClient/geometryParser.ts b/src/externalClients/layersClient/geometryParser.ts index eac59a0..a8ddfbe 100644 --- a/src/externalClients/layersClient/geometryParser.ts +++ b/src/externalClients/layersClient/geometryParser.ts @@ -1,5 +1,4 @@ import { point, lineString, polygon } from '@turf/helpers'; -import type { Logger } from '@map-colonies/js-logger'; import type { Geometry, LineString, Point, Polygon, Position } from 'geojson'; export interface RawCoordinate { @@ -18,43 +17,36 @@ function toPosition(c: RawCoordinate): Position { return [c.longitude, c.latitude]; } -export function geographyToGeoJSON(logger: Logger, geography: RawGeography): Geometry { - try { - const kind = geography.graphicsObjectKind.value.toUpperCase(); - const coords = geography.coordinates; - - if (coords.length === 0) { - throw new Error(`Empty coordinates for graphicsObjectKind=${kind}`); - } - - switch (kind) { - case 'POINT': - return point(toPosition(coords[0]!)).geometry as Point; - - case 'LINE': - case 'LINESTRING': - if (coords.length < 2) { - throw new Error(`LineString requires >=2 coordinates, got ${coords.length}`); - } - return lineString(coords.map(toPosition)).geometry as LineString; - - case 'POLYGON': - case 'AREA': - if (coords.length < 4) { - throw new Error(`Polygon requires >=4 coordinates (closed ring), got ${coords.length}`); - } - return polygon([coords.map(toPosition)]).geometry as Polygon; - - default: - if (MULTI_KINDS.has(kind)) { - logger.error({ msg: 'geographyToGeoJSON unsupported MULTI* kind', geography }); - throw new Error(`Unsupported graphicsObjectKind=${kind}: MULTI* encoding not yet documented`); - } - logger.error({ msg: 'geographyToGeoJSON unknown kind', geography }); - throw new Error(`Unknown graphicsObjectKind=${kind}`); - } - } catch (err) { - logger.error({ msg: 'geographyToGeoJSON failed', geography, err }); - throw err; +export function geographyToGeoJSON(geography: RawGeography): Geometry { + const kind = geography.graphicsObjectKind.value.toUpperCase(); + const coords = geography.coordinates; + + if (coords.length === 0) { + throw new Error(`Empty coordinates for graphicsObjectKind=${kind}`); + } + + switch (kind) { + case 'POINT': + return point(toPosition(coords[0]!)).geometry as Point; + + case 'LINE': + case 'LINESTRING': + if (coords.length < 2) { + throw new Error(`LineString requires >=2 coordinates, got ${coords.length}`); + } + return lineString(coords.map(toPosition)).geometry as LineString; + + case 'POLYGON': + case 'AREA': + if (coords.length < 4) { + throw new Error(`Polygon requires >=4 coordinates (closed ring), got ${coords.length}`); + } + return polygon([coords.map(toPosition)]).geometry as Polygon; + + default: + if (MULTI_KINDS.has(kind)) { + throw new Error(`Unsupported graphicsObjectKind=${kind}: MULTI* encoding not yet documented`); + } + throw new Error(`Unknown graphicsObjectKind=${kind}`); } } diff --git a/src/externalClients/layersClient/layersClient.ts b/src/externalClients/layersClient/layersClient.ts index 7ab0cf8..1c1c27e 100644 --- a/src/externalClients/layersClient/layersClient.ts +++ b/src/externalClients/layersClient/layersClient.ts @@ -40,9 +40,16 @@ interface GraphQLResponse { const tracer = trace.getTracer(SERVICE_NAME); function toLayerObject(logger: Logger, raw: RawLayerObject): LayerObject { + let geom; + try { + geom = geographyToGeoJSON(raw.geography); + } catch (err) { + logger.error({ msg: 'geographyToGeoJSON failed', geography: raw.geography, err }); + throw err; + } return { id: raw.id, - geom: geographyToGeoJSON(logger, raw.geography), + geom, properties: { createdBy: raw.createdBy, creationTime: raw.creationTime, diff --git a/tests/unit/externalClients/geometryParser.spec.ts b/tests/unit/externalClients/geometryParser.spec.ts index fb0ca5b..a02937d 100644 --- a/tests/unit/externalClients/geometryParser.spec.ts +++ b/tests/unit/externalClients/geometryParser.spec.ts @@ -1,16 +1,6 @@ import { describe, expect, it } from 'vitest'; -import type { Logger } from '@map-colonies/js-logger'; import { geographyToGeoJSON, type RawGeography } from '@src/externalClients/layersClient/geometryParser'; -const logger = { - error: () => undefined, - info: () => undefined, - debug: () => undefined, - warn: () => undefined, - fatal: () => undefined, - trace: () => undefined, -} as unknown as Logger; - function geo(kind: string, coords: { latitude: number; longitude: number }[]): RawGeography { return { coordinates: coords, graphicsObjectKind: { value: kind } }; } @@ -18,12 +8,12 @@ function geo(kind: string, coords: { latitude: number; longitude: number }[]): R describe('geographyToGeoJSON', () => { describe('POINT', () => { it('maps single coordinate to Point with [lng, lat] order', () => { - const result = geographyToGeoJSON(logger, geo('POINT', [{ latitude: 32.0853, longitude: 34.7818 }])); + const result = geographyToGeoJSON(geo('POINT', [{ latitude: 32.0853, longitude: 34.7818 }])); expect(result).toEqual({ type: 'Point', coordinates: [34.7818, 32.0853] }); }); it('accepts lowercase kind', () => { - const result = geographyToGeoJSON(logger, geo('point', [{ latitude: 1, longitude: 2 }])); + const result = geographyToGeoJSON(geo('point', [{ latitude: 1, longitude: 2 }])); expect(result).toEqual({ type: 'Point', coordinates: [2, 1] }); }); }); @@ -31,7 +21,6 @@ describe('geographyToGeoJSON', () => { describe('LINE / LINESTRING', () => { it('maps 2+ coords to LineString in [lng, lat] order', () => { const result = geographyToGeoJSON( - logger, geo('LINE', [ { latitude: 32.7453754, longitude: 35.1867382 }, { latitude: 32.7454701, longitude: 35.1854494 }, @@ -48,7 +37,6 @@ describe('geographyToGeoJSON', () => { it('accepts LINESTRING alias', () => { const result = geographyToGeoJSON( - logger, geo('LINESTRING', [ { latitude: 1, longitude: 2 }, { latitude: 3, longitude: 4 }, @@ -58,7 +46,7 @@ describe('geographyToGeoJSON', () => { }); it('throws when fewer than 2 coords', () => { - expect(() => geographyToGeoJSON(logger, geo('LINE', [{ latitude: 1, longitude: 2 }]))).toThrow(/LineString requires >=2/); + expect(() => geographyToGeoJSON(geo('LINE', [{ latitude: 1, longitude: 2 }]))).toThrow(/LineString requires >=2/); }); }); @@ -70,7 +58,7 @@ describe('geographyToGeoJSON', () => { { latitude: 1, longitude: 1 }, { latitude: 0, longitude: 0 }, ]; - const result = geographyToGeoJSON(logger, geo('POLYGON', ring)); + const result = geographyToGeoJSON(geo('POLYGON', ring)); expect(result).toEqual({ type: 'Polygon', coordinates: [ @@ -90,7 +78,7 @@ describe('geographyToGeoJSON', () => { { latitude: 1, longitude: 1 }, { latitude: 0, longitude: 0 }, ]; - expect(() => geographyToGeoJSON(logger, geo('POLYGON', ring))).toThrow(/Polygon requires >=4/); + expect(() => geographyToGeoJSON(geo('POLYGON', ring))).toThrow(/Polygon requires >=4/); }); it('accepts AREA alias as Polygon', () => { @@ -100,7 +88,7 @@ describe('geographyToGeoJSON', () => { { latitude: 1, longitude: 1 }, { latitude: 0, longitude: 0 }, ]; - const result = geographyToGeoJSON(logger, geo('AREA', ring)); + const result = geographyToGeoJSON(geo('AREA', ring)); expect(result).toEqual({ type: 'Polygon', coordinates: [ @@ -117,15 +105,15 @@ describe('geographyToGeoJSON', () => { describe('error cases', () => { it('throws on empty coordinates', () => { - expect(() => geographyToGeoJSON(logger, geo('POINT', []))).toThrow(/Empty coordinates/); + expect(() => geographyToGeoJSON(geo('POINT', []))).toThrow(/Empty coordinates/); }); it.each(['MULTIPOINT', 'MULTILINE', 'MULTILINESTRING', 'MULTIPOLYGON'])('throws unsupported for %s', (kind) => { - expect(() => geographyToGeoJSON(logger, geo(kind, [{ latitude: 1, longitude: 2 }]))).toThrow(/Unsupported graphicsObjectKind/); + expect(() => geographyToGeoJSON(geo(kind, [{ latitude: 1, longitude: 2 }]))).toThrow(/Unsupported graphicsObjectKind/); }); it('throws on unknown kind', () => { - expect(() => geographyToGeoJSON(logger, geo('TRIANGLE', [{ latitude: 1, longitude: 2 }]))).toThrow(/Unknown graphicsObjectKind=TRIANGLE/); + expect(() => geographyToGeoJSON(geo('TRIANGLE', [{ latitude: 1, longitude: 2 }]))).toThrow(/Unknown graphicsObjectKind=TRIANGLE/); }); }); }); From 203f69da4cdfd818859723cff6aefc62df3656cf Mon Sep 17 00:00:00 2001 From: Ron Israeli Date: Tue, 26 May 2026 14:36:48 +0300 Subject: [PATCH 5/5] test(sync): update fetchPage assertion for logger arg Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/unit/handler/layerSyncHandler.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/handler/layerSyncHandler.spec.ts b/tests/unit/handler/layerSyncHandler.spec.ts index 1c82fde..7991ed8 100644 --- a/tests/unit/handler/layerSyncHandler.spec.ts +++ b/tests/unit/handler/layerSyncHandler.spec.ts @@ -98,7 +98,7 @@ describe('layerSyncHandler', () => { const entry: ScheduleEntry = { layerName: 'obstacles', nextRunAt: 0 }; await fetchAndSyncLayerPage(makeLogger(), entry); - expect(layerClient.fetchPage).toHaveBeenCalledWith('obstacles', '5'); + expect(layerClient.fetchPage).toHaveBeenCalledWith(expect.anything(), 'obstacles', '5'); expect(layerDataRepository.insertObjects).toHaveBeenCalledWith('obstacles', objects); expect(layerDataRepository.deleteDeprecatedObjects).toHaveBeenCalledWith('obstacles', ['old-1']); expect(syncStateRepository.updateSequence).toHaveBeenCalledWith('obstacles', '10');