From 3af8e09517e889bb2368f0fa58ae4c44b3140c3e Mon Sep 17 00:00:00 2001 From: David Stone Date: Thu, 4 Jun 2026 13:57:13 +0100 Subject: [PATCH 1/2] Interactive map - replace UMD with ESM --- jest.config.cjs | 10 + package-lock.json | 9 +- package.json | 1 + src/client/javascripts/geospatial-map.js | 14 +- src/client/javascripts/map.js | 31 +- src/client/stylesheets/shared.scss | 7 + test/__mocks__/@defra/interactive-map.js | 1 + .../interactive-map/plugins/datasets.js | 1 + .../plugins/datasets/adapters/maplibre.js | 1 + .../@defra/interactive-map/plugins/draw-ml.js | 1 + .../interactive-map/plugins/interact.js | 1 + .../interactive-map/plugins/map-styles.js | 1 + .../interactive-map/plugins/scale-bar.js | 1 + .../@defra/interactive-map/plugins/search.js | 1 + .../interactive-map/providers/maplibre.js | 1 + test/client/javascripts/map.test.js | 405 +++++++++--------- 16 files changed, 260 insertions(+), 226 deletions(-) create mode 100644 test/__mocks__/@defra/interactive-map.js create mode 100644 test/__mocks__/@defra/interactive-map/plugins/datasets.js create mode 100644 test/__mocks__/@defra/interactive-map/plugins/datasets/adapters/maplibre.js create mode 100644 test/__mocks__/@defra/interactive-map/plugins/draw-ml.js create mode 100644 test/__mocks__/@defra/interactive-map/plugins/interact.js create mode 100644 test/__mocks__/@defra/interactive-map/plugins/map-styles.js create mode 100644 test/__mocks__/@defra/interactive-map/plugins/scale-bar.js create mode 100644 test/__mocks__/@defra/interactive-map/plugins/search.js create mode 100644 test/__mocks__/@defra/interactive-map/providers/maplibre.js diff --git a/jest.config.cjs b/jest.config.cjs index 8b8c7ee26..86d6cfa6b 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -57,6 +57,16 @@ module.exports = { 'geodesy' // Supports ESM only ].join('|')}/)` ], + moduleNameMapper: { + '^@defra/interactive-map$': + '/test/__mocks__/@defra/interactive-map.js', + '^@defra/interactive-map/plugins/datasets/adapters/(.*)$': + '/test/__mocks__/@defra/interactive-map/plugins/datasets/adapters/$1.js', + '^@defra/interactive-map/plugins/(.*)$': + '/test/__mocks__/@defra/interactive-map/plugins/$1.js', + '^@defra/interactive-map/providers/(.*)$': + '/test/__mocks__/@defra/interactive-map/providers/$1.js' + }, testTimeout: 10000, forceExit: true } diff --git a/package-lock.json b/package-lock.json index 9f63bcc91..fc0609876 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,6 +53,7 @@ "joi": "^17.13.3", "liquidjs": "^10.24.0", "lodash": "^4.17.21", + "maplibre-gl": "^5.24.0", "marked": "^15.0.12", "nunjucks": "^3.2.4", "obscenity": "^0.4.5", @@ -23518,14 +23519,14 @@ } }, "node_modules/maplibre-gl": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.23.0.tgz", - "integrity": "sha512-aou8YBNFS8uVtDWFWt0W/6oorfl18wt+oIA8fnXk1kivjkbtXi9gGrQvflTpwrR3hG13aWdIdbYWeN0NFMV7ag==", + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.24.0.tgz", + "integrity": "sha512-ALyFxgtd5R+65UqZ/++lOqwWcC0SNho9c27fYSyLmG7AfnAul2o46F05aDJGPbFU57wos9dgcIySHs0Xe6ia3A==", "license": "BSD-3-Clause", "dependencies": { "@mapbox/jsonlint-lines-primitives": "^2.0.2", "@mapbox/point-geometry": "^1.1.0", - "@mapbox/tiny-sdf": "^2.0.7", + "@mapbox/tiny-sdf": "^2.1.0", "@mapbox/unitbezier": "^0.0.1", "@mapbox/vector-tile": "^2.0.4", "@mapbox/whoots-js": "^3.1.0", diff --git a/package.json b/package.json index 415cbfce7..c2fe13540 100644 --- a/package.json +++ b/package.json @@ -130,6 +130,7 @@ "joi": "^17.13.3", "liquidjs": "^10.24.0", "lodash": "^4.17.21", + "maplibre-gl": "^5.24.0", "marked": "^15.0.12", "nunjucks": "^3.2.4", "obscenity": "^0.4.5", diff --git a/src/client/javascripts/geospatial-map.js b/src/client/javascripts/geospatial-map.js index cbdda3d52..8311e30fa 100644 --- a/src/client/javascripts/geospatial-map.js +++ b/src/client/javascripts/geospatial-map.js @@ -1,3 +1,9 @@ +// @ts-expect-error - no types +import createDatasetsPlugin from '@defra/interactive-map/plugins/datasets' +// @ts-expect-error - no types +import { maplibreLayerAdapter } from '@defra/interactive-map/plugins/datasets/adapters/maplibre' +// @ts-expect-error - no types +import createDrawPlugin from '@defra/interactive-map/plugins/draw-ml' import { bbox } from '@turf/bbox' import { @@ -151,9 +157,6 @@ export function getBoundingBox(geojson) { * @param {number} index - the 0-based index */ export function processGeospatial(config, geospatial, index) { - // @ts-expect-error - Defra namespace currently comes from UMD support files - const defra = window.defra - if (!(geospatial instanceof HTMLDivElement)) { return } @@ -166,14 +169,15 @@ export function processGeospatial(config, geospatial, index) { const { listEl, mapId } = createContainers(geospatialInput, index) const geojson = getGeoJSON(geospatialInput) const bounds = geojson.features.length ? getBoundingBox(geojson) : undefined - const drawPlugin = defra.drawMLPlugin() + const drawPlugin = createDrawPlugin() const plugins = [drawPlugin] const country = geospatial.dataset.country if (country) { // Add the country bounds as a dataset plugin to show the valid area on the map // and provide feedback to the user when they add features outside of the bounds. - const datasetsPlugin = defra.datasetsMaplibrePlugin({ + const datasetsPlugin = createDatasetsPlugin({ + layerAdapter: maplibreLayerAdapter, datasets: [ { id: 'invalid-area', diff --git a/src/client/javascripts/map.js b/src/client/javascripts/map.js index 07f69a5d6..928a4f52e 100644 --- a/src/client/javascripts/map.js +++ b/src/client/javascripts/map.js @@ -1,3 +1,15 @@ +// @ts-expect-error - no types +import InteractiveMap from '@defra/interactive-map' +// @ts-expect-error - no types +import createInteractPlugin from '@defra/interactive-map/plugins/interact' +// @ts-expect-error - no types +import createMapStylesPlugin from '@defra/interactive-map/plugins/map-styles' +// @ts-expect-error - no types +import createScaleBarPlugin from '@defra/interactive-map/plugins/scale-bar' +// @ts-expect-error - no types +import createSearchPlugin from '@defra/interactive-map/plugins/search' +// @ts-expect-error - no types +import maplibreProvider from '@defra/interactive-map/providers/maplibre' import { centroid } from '@turf/centroid' // @ts-expect-error - no types import OsGridRef, { LatLon } from 'geodesy/osgridref.js' @@ -249,24 +261,17 @@ export function makeTileRequestTransformer(apiPath) { export function createMap(mapId, initConfig, mapsConfig) { const { assetPath, apiPath, data = defaultData } = mapsConfig const logoAltText = 'Ordnance survey logo' - - // @ts-expect-error - Defra namespace currently comes from UMD support files - const defra = window.defra - - const interactPlugin = defra.interactPlugin({ + const interactPlugin = createInteractPlugin({ markerColor: { outdoor: '#ff0000', dark: '#00ff00' }, interactionModes: ['placeMarker'], multiSelect: false }) /** @type {InteractiveMap} */ - const map = new defra.InteractiveMap(mapId, { + const map = new InteractiveMap(mapId, { enableFullscreen: true, autoColorScheme: false, - mapProvider: defra.maplibreProvider(), - reverseGeocodeProvider: defra.openNamesProvider({ - url: `${apiPath}/reverse-geocode-proxy?easting={easting}&northing={northing}` - }), + mapProvider: maplibreProvider(), behaviour: 'inline', minZoom: 6, maxZoom: 18, @@ -275,7 +280,7 @@ export function createMap(mapId, initConfig, mapsConfig) { transformRequest: makeTileRequestTransformer(apiPath), ...initConfig, plugins: [ - defra.mapStylesPlugin({ + createMapStylesPlugin({ mapStyles: [ { id: 'outdoor', @@ -319,12 +324,12 @@ export function createMap(mapId, initConfig, mapsConfig) { ] }), interactPlugin, - defra.searchPlugin({ + createSearchPlugin({ osNamesURL: `${apiPath}/geocode-proxy?query={query}`, width: '300px', showMarker: false }), - defra.scaleBarPlugin({ + createScaleBarPlugin({ units: 'metric' }), ...(initConfig.plugins ?? []) diff --git a/src/client/stylesheets/shared.scss b/src/client/stylesheets/shared.scss index 963c6156c..7ea9edf00 100644 --- a/src/client/stylesheets/shared.scss +++ b/src/client/stylesheets/shared.scss @@ -4,6 +4,13 @@ @use "summary-list"; @use "location-fields"; +@use "@defra/interactive-map/css" as core; +@use "@defra/interactive-map/plugins/interact/css" as interact; +@use "@defra/interactive-map/plugins/map-styles/css" as mapStyles; +@use "@defra/interactive-map/plugins/search/css" as search; +@use "@defra/interactive-map/plugins/scale-bar/css" as scaleBar; +@use "@defra/interactive-map/plugins/draw-ml/css" as drawMl; + // Use default GDS Transport font for autocomplete .autocomplete__hint, .autocomplete__input, diff --git a/test/__mocks__/@defra/interactive-map.js b/test/__mocks__/@defra/interactive-map.js new file mode 100644 index 000000000..b4bbacb11 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map.js @@ -0,0 +1 @@ +module.exports = jest.fn() diff --git a/test/__mocks__/@defra/interactive-map/plugins/datasets.js b/test/__mocks__/@defra/interactive-map/plugins/datasets.js new file mode 100644 index 000000000..b4bbacb11 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map/plugins/datasets.js @@ -0,0 +1 @@ +module.exports = jest.fn() diff --git a/test/__mocks__/@defra/interactive-map/plugins/datasets/adapters/maplibre.js b/test/__mocks__/@defra/interactive-map/plugins/datasets/adapters/maplibre.js new file mode 100644 index 000000000..fdec31c76 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map/plugins/datasets/adapters/maplibre.js @@ -0,0 +1 @@ +exports.maplibreLayerAdapter = {} diff --git a/test/__mocks__/@defra/interactive-map/plugins/draw-ml.js b/test/__mocks__/@defra/interactive-map/plugins/draw-ml.js new file mode 100644 index 000000000..b4bbacb11 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map/plugins/draw-ml.js @@ -0,0 +1 @@ +module.exports = jest.fn() diff --git a/test/__mocks__/@defra/interactive-map/plugins/interact.js b/test/__mocks__/@defra/interactive-map/plugins/interact.js new file mode 100644 index 000000000..b4bbacb11 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map/plugins/interact.js @@ -0,0 +1 @@ +module.exports = jest.fn() diff --git a/test/__mocks__/@defra/interactive-map/plugins/map-styles.js b/test/__mocks__/@defra/interactive-map/plugins/map-styles.js new file mode 100644 index 000000000..b4bbacb11 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map/plugins/map-styles.js @@ -0,0 +1 @@ +module.exports = jest.fn() diff --git a/test/__mocks__/@defra/interactive-map/plugins/scale-bar.js b/test/__mocks__/@defra/interactive-map/plugins/scale-bar.js new file mode 100644 index 000000000..b4bbacb11 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map/plugins/scale-bar.js @@ -0,0 +1 @@ +module.exports = jest.fn() diff --git a/test/__mocks__/@defra/interactive-map/plugins/search.js b/test/__mocks__/@defra/interactive-map/plugins/search.js new file mode 100644 index 000000000..b4bbacb11 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map/plugins/search.js @@ -0,0 +1 @@ +module.exports = jest.fn() diff --git a/test/__mocks__/@defra/interactive-map/providers/maplibre.js b/test/__mocks__/@defra/interactive-map/providers/maplibre.js new file mode 100644 index 000000000..b4bbacb11 --- /dev/null +++ b/test/__mocks__/@defra/interactive-map/providers/maplibre.js @@ -0,0 +1 @@ +module.exports = jest.fn() diff --git a/test/client/javascripts/map.test.js b/test/client/javascripts/map.test.js index deea56697..d691b4462 100644 --- a/test/client/javascripts/map.test.js +++ b/test/client/javascripts/map.test.js @@ -1,3 +1,21 @@ +// Module-level mocks for @defra/interactive-map and its plugins +// @ts-expect-error - no types +import InteractiveMap from '@defra/interactive-map' +// @ts-expect-error - no types +import createDatasetsPlugin from '@defra/interactive-map/plugins/datasets' +// @ts-expect-error - no types +import createDrawPlugin from '@defra/interactive-map/plugins/draw-ml' +// @ts-expect-error - no types +import createInteractPlugin from '@defra/interactive-map/plugins/interact' +// @ts-expect-error - no types +import createMapStylesPlugin from '@defra/interactive-map/plugins/map-styles' +// @ts-expect-error - no types +import createScaleBarPlugin from '@defra/interactive-map/plugins/scale-bar' +// @ts-expect-error - no types +import createSearchPlugin from '@defra/interactive-map/plugins/search' +// @ts-expect-error - no types +import maplibreProvider from '@defra/interactive-map/providers/maplibre' + import { createFeatureHTML, createFeaturesHTML, @@ -12,113 +30,89 @@ import { makeTileRequestTransformer } from '~/src/client/javascripts/map.js' -describe('Maps Client JS', () => { - /** @type {jest.Mock} */ - let onMock - - /** @type {jest.Mock} */ - let addMarkerMock - - /** @type {jest.Mock} */ - let removeMarkerMock - - /** @type {jest.Mock} */ - let addPanelMock - - /** @type {jest.Mock} */ - let addButtonMock - - /** @type {jest.Mock} */ - let interactPlugin - - /** @type {jest.Mock} */ - let interactPluginSelectFeature - - /** @type {jest.Mock} */ - let interactPluginEnable - - /** @type {jest.Mock} */ - let interactPluginDisable - - /** @type {jest.Mock} */ - let drawMLPlugin - - /** @type {jest.Mock} */ - let drawPluginAddFeature - - /** @type {jest.Mock} */ - let drawPluginEditFeature - - /** @type {jest.Mock} */ - let drawPluginNewPolygon - - /** @type {jest.Mock} */ - let drawPluginNewLine - - /** @type {jest.Mock} */ - let drawPluginDeleteFeature - - /** @type {jest.Mock} */ - let toggleButtonStateMock - - /** @type {jest.Mock} */ - let datasetsMaplibrePlugin +/** @type {jest.Mock} */ +let mockOn +/** @type {jest.Mock} */ +let mockAddMarker +/** @type {jest.Mock} */ +let mockRemoveMarker +/** @type {jest.Mock} */ +let mockAddPanel +/** @type {jest.Mock} */ +let mockAddButton +/** @type {jest.Mock} */ +let mockToggleButtonState + +/** @type {jest.Mock} */ +let mockInteractPluginSelectFeature +/** @type {jest.Mock} */ +let mockInteractPluginEnable +/** @type {jest.Mock} */ +let mockInteractPluginDisable + +/** @type {jest.Mock} */ +let mockDrawPluginAddFeature +/** @type {jest.Mock} */ +let mockDrawPluginEditFeature +/** @type {jest.Mock} */ +let mockDrawPluginNewPolygon +/** @type {jest.Mock} */ +let mockDrawPluginNewLine +/** @type {jest.Mock} */ +let mockDrawPluginDeleteFeature +/** @type {jest.Mock} */ +let mockDatasetsMaplibrePlugin +describe('Maps Client JS', () => { beforeEach(() => { jest.resetAllMocks() // eslint-disable-next-line @typescript-eslint/no-empty-function const noop = () => {} - onMock = jest.fn() - addMarkerMock = jest.fn() - removeMarkerMock = jest.fn() - addPanelMock = jest.fn() - addButtonMock = jest.fn() - toggleButtonStateMock = jest.fn() - interactPluginSelectFeature = jest.fn() - interactPluginEnable = jest.fn() - interactPluginDisable = jest.fn() - drawPluginAddFeature = jest.fn() - drawPluginEditFeature = jest.fn() - drawPluginDeleteFeature = jest.fn() - drawPluginNewPolygon = jest.fn() - drawPluginNewLine = jest.fn() - interactPlugin = jest.fn(() => ({ - selectFeature: interactPluginSelectFeature, - enable: interactPluginEnable, - disable: interactPluginDisable + mockOn = jest.fn() + mockAddMarker = jest.fn() + mockRemoveMarker = jest.fn() + mockAddPanel = jest.fn() + mockAddButton = jest.fn() + mockToggleButtonState = jest.fn() + mockInteractPluginSelectFeature = jest.fn() + mockInteractPluginEnable = jest.fn() + mockInteractPluginDisable = jest.fn() + mockDrawPluginAddFeature = jest.fn() + mockDrawPluginEditFeature = jest.fn() + mockDrawPluginDeleteFeature = jest.fn() + mockDrawPluginNewPolygon = jest.fn() + mockDrawPluginNewLine = jest.fn() + mockDatasetsMaplibrePlugin = jest.fn() + InteractiveMap.mockImplementation(() => ({ + on: (/** @type {any} */ ...args) => mockOn(...args), + addMarker: (/** @type {any} */ ...args) => mockAddMarker(...args), + removeMarker: (/** @type {any} */ ...args) => mockRemoveMarker(...args), + addPanel: (/** @type {any} */ ...args) => mockAddPanel(...args), + addButton: (/** @type {any} */ ...args) => mockAddButton(...args), + toggleButtonState: (/** @type {any} */ ...args) => + mockToggleButtonState(...args) })) - drawMLPlugin = jest.fn(() => ({ - addFeature: drawPluginAddFeature, - editFeature: drawPluginEditFeature, - deleteFeature: drawPluginDeleteFeature, - newPolygon: drawPluginNewPolygon, - newLine: drawPluginNewLine + createInteractPlugin.mockImplementation(() => ({ + selectFeature: mockInteractPluginSelectFeature, + enable: mockInteractPluginEnable, + disable: mockInteractPluginDisable })) - datasetsMaplibrePlugin = jest.fn() - - class MockInteractiveMap { - on = onMock - addMarker = addMarkerMock - removeMarker = removeMarkerMock - addPanel = addPanelMock - addButton = addButtonMock - toggleButtonState = toggleButtonStateMock - } - - // @ts-expect-error - loaded via UMD - window.defra = { - InteractiveMap: MockInteractiveMap, - maplibreProvider: noop, - openNamesProvider: noop, - mapStylesPlugin: noop, - interactPlugin, - searchPlugin: noop, - zoomControlsPlugin: noop, - scaleBarPlugin: noop, - drawMLPlugin, - datasetsMaplibrePlugin - } + createDrawPlugin.mockImplementation(() => ({ + addFeature: mockDrawPluginAddFeature, + editFeature: mockDrawPluginEditFeature, + deleteFeature: mockDrawPluginDeleteFeature, + newPolygon: mockDrawPluginNewPolygon, + newLine: mockDrawPluginNewLine + })) + createDatasetsPlugin.mockImplementation((/** @type {any} */ opts) => + mockDatasetsMaplibrePlugin(opts) + ) + + maplibreProvider.mockImplementation(noop) + createMapStylesPlugin.mockImplementation(noop) + createSearchPlugin.mockImplementation(noop) + createScaleBarPlugin.mockImplementation(noop) }) afterEach(() => { @@ -171,12 +165,12 @@ describe('Maps Client JS', () => { describe('Map initialisation', () => { test('initMaps initializes without errors when DOM elements are present', () => { expect(() => initMaps()).not.toThrow() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'map:ready', expect.any(Function) ) - const onMapReady = onMock.mock.calls[0][1] + const onMapReady = mockOn.mock.calls[0][1] expect(typeof onMapReady).toBe('function') // Manually invoke onMapReady callback @@ -187,11 +181,11 @@ describe('Maps Client JS', () => { } }) - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(interactPluginEnable).toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockInteractPluginEnable).toHaveBeenCalled() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'interact:markerchange', expect.any(Function) ) @@ -209,10 +203,10 @@ describe('Maps Client JS', () => { longInput.dispatchEvent(new window.Event('change')) // Expect it to update once, only when both fields are valid - expect(addMarkerMock).toHaveBeenCalledTimes(1) + expect(mockAddMarker).toHaveBeenCalledTimes(1) expect(flyToMock).toHaveBeenCalledTimes(1) - const onInteractMarkerChange = onMock.mock.calls[1][1] + const onInteractMarkerChange = mockOn.mock.calls[1][1] expect(typeof onInteractMarkerChange).toBe('function') onInteractMarkerChange({ coords: [-2.1478238, 54.155676] }) }) @@ -229,12 +223,12 @@ describe('Maps Client JS', () => { longInput.value = '-1.522781' expect(() => initMaps()).not.toThrow() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'map:ready', expect.any(Function) ) - const onMapReady = onMock.mock.calls[0][1] + const onMapReady = mockOn.mock.calls[0][1] expect(typeof onMapReady).toBe('function') // Manually invoke onMapReady callback @@ -245,11 +239,11 @@ describe('Maps Client JS', () => { } }) - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(interactPluginEnable).toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockInteractPluginEnable).toHaveBeenCalled() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'interact:markerchange', expect.any(Function) ) @@ -261,7 +255,7 @@ describe('Maps Client JS', () => { longInput.dispatchEvent(new window.Event('change')) // Expect it to update twice as both fields are already valid - expect(addMarkerMock).toHaveBeenCalledTimes(2) + expect(mockAddMarker).toHaveBeenCalledTimes(2) expect(flyToMock).toHaveBeenCalledTimes(2) }) @@ -274,7 +268,7 @@ describe('Maps Client JS', () => { }) expect(() => initMaps()).not.toThrow() - expect(onMock).not.toHaveBeenCalled() + expect(mockOn).not.toHaveBeenCalled() }) test('initMaps only applies when there are supported location components on the page', () => { @@ -286,7 +280,7 @@ describe('Maps Client JS', () => { }) expect(() => initMaps()).not.toThrow() - expect(onMock).not.toHaveBeenCalled() + expect(mockOn).not.toHaveBeenCalled() }) }) }) @@ -373,12 +367,12 @@ describe('Maps Client JS', () => { describe('Map initialisation', () => { test('initMaps easting northing initializes without errors when DOM elements are present', () => { expect(() => initMaps()).not.toThrow() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'map:ready', expect.any(Function) ) - const onMapReady = onMock.mock.calls[0][1] + const onMapReady = mockOn.mock.calls[0][1] expect(typeof onMapReady).toBe('function') // Manually invoke onMapReady callback @@ -389,11 +383,11 @@ describe('Maps Client JS', () => { } }) - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(interactPluginEnable).toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockInteractPluginEnable).toHaveBeenCalled() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'interact:markerchange', expect.any(Function) ) @@ -411,10 +405,10 @@ describe('Maps Client JS', () => { northingInput.dispatchEvent(new window.Event('change')) // Expect it to update once, only when both fields are valid - expect(addMarkerMock).toHaveBeenCalledTimes(1) + expect(mockAddMarker).toHaveBeenCalledTimes(1) expect(flyToMock).toHaveBeenCalledTimes(1) - const onInteractMarkerChange = onMock.mock.calls[1][1] + const onInteractMarkerChange = mockOn.mock.calls[1][1] expect(typeof onInteractMarkerChange).toBe('function') onInteractMarkerChange({ coords: [-2.147823, 54.155676] @@ -433,12 +427,12 @@ describe('Maps Client JS', () => { northingInput.value = '427585' expect(() => initMaps()).not.toThrow() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'map:ready', expect.any(Function) ) - const onMapReady = onMock.mock.calls[0][1] + const onMapReady = mockOn.mock.calls[0][1] expect(typeof onMapReady).toBe('function') // Manually invoke onMapReady callback @@ -449,11 +443,11 @@ describe('Maps Client JS', () => { } }) - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(interactPluginEnable).toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockInteractPluginEnable).toHaveBeenCalled() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'interact:markerchange', expect.any(Function) ) @@ -465,7 +459,7 @@ describe('Maps Client JS', () => { northingInput.dispatchEvent(new window.Event('change')) // Expect it to update twice as both fields are already valid - expect(addMarkerMock).toHaveBeenCalledTimes(2) + expect(mockAddMarker).toHaveBeenCalledTimes(2) expect(flyToMock).toHaveBeenCalledTimes(2) }) @@ -478,7 +472,7 @@ describe('Maps Client JS', () => { }) expect(() => initMaps()).not.toThrow() - expect(onMock).not.toHaveBeenCalled() + expect(mockOn).not.toHaveBeenCalled() }) test('initMaps only applies when there are supported location components on the page', () => { @@ -490,7 +484,7 @@ describe('Maps Client JS', () => { }) expect(() => initMaps()).not.toThrow() - expect(onMock).not.toHaveBeenCalled() + expect(mockOn).not.toHaveBeenCalled() }) }) }) @@ -524,12 +518,12 @@ describe('Maps Client JS', () => { describe('Map initialisation', () => { test('initMaps os grid reference initializes without errors when DOM elements are present', () => { expect(() => initMaps()).not.toThrow() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'map:ready', expect.any(Function) ) - const onMapReady = onMock.mock.calls[0][1] + const onMapReady = mockOn.mock.calls[0][1] expect(typeof onMapReady).toBe('function') // Manually invoke onMapReady callback @@ -540,11 +534,11 @@ describe('Maps Client JS', () => { } }) - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(interactPluginEnable).toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockInteractPluginEnable).toHaveBeenCalled() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'interact:markerchange', expect.any(Function) ) @@ -558,10 +552,10 @@ describe('Maps Client JS', () => { osGridRefInput.dispatchEvent(new window.Event('change')) // Expect it to update once - expect(addMarkerMock).toHaveBeenCalledTimes(1) + expect(mockAddMarker).toHaveBeenCalledTimes(1) expect(flyToMock).toHaveBeenCalledTimes(1) - const onInteractMarkerChange = onMock.mock.calls[1][1] + const onInteractMarkerChange = mockOn.mock.calls[1][1] expect(typeof onInteractMarkerChange).toBe('function') onInteractMarkerChange({ coords: [-2.147823, 54.155676] @@ -578,12 +572,12 @@ describe('Maps Client JS', () => { osGridRefInput.value = 'SJ 61831 71500' expect(() => initMaps()).not.toThrow() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'map:ready', expect.any(Function) ) - const onMapReady = onMock.mock.calls[0][1] + const onMapReady = mockOn.mock.calls[0][1] expect(typeof onMapReady).toBe('function') // Manually invoke onMapReady callback @@ -594,11 +588,11 @@ describe('Maps Client JS', () => { } }) - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(interactPluginEnable).toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockInteractPluginEnable).toHaveBeenCalled() - expect(onMock).toHaveBeenLastCalledWith( + expect(mockOn).toHaveBeenLastCalledWith( 'interact:markerchange', expect.any(Function) ) @@ -607,7 +601,7 @@ describe('Maps Client JS', () => { osGridRefInput.dispatchEvent(new window.Event('change')) // Expect it to update once as the field is valid - expect(addMarkerMock).toHaveBeenCalledTimes(1) + expect(mockAddMarker).toHaveBeenCalledTimes(1) expect(flyToMock).toHaveBeenCalledTimes(1) }) @@ -620,7 +614,7 @@ describe('Maps Client JS', () => { }) expect(() => initMaps()).not.toThrow() - expect(onMock).not.toHaveBeenCalled() + expect(mockOn).not.toHaveBeenCalled() }) test('initMaps only applies when there are supported location components on the page', () => { @@ -632,7 +626,7 @@ describe('Maps Client JS', () => { }) expect(() => initMaps()).not.toThrow() - expect(onMock).not.toHaveBeenCalled() + expect(mockOn).not.toHaveBeenCalled() }) }) }) @@ -735,47 +729,47 @@ describe('Maps Client JS', () => { : '' expect(() => initMaps()).not.toThrow() - expect(onMock).toHaveBeenCalledTimes(1) - expect(onMock).toHaveBeenNthCalledWith( + expect(mockOn).toHaveBeenCalledTimes(1) + expect(mockOn).toHaveBeenNthCalledWith( 1, 'map:ready', expect.any(Function) ) - const onMapReady = onMock.mock.calls[0][1] + const onMapReady = mockOn.mock.calls[0][1] expect(typeof onMapReady).toBe('function') // Manually invoke onMapReady callback onMapReady({}) - expect(onMock).toHaveBeenCalledTimes(6) - expect(onMock).toHaveBeenNthCalledWith( + expect(mockOn).toHaveBeenCalledTimes(6) + expect(mockOn).toHaveBeenNthCalledWith( 2, 'draw:ready', expect.any(Function) ) - expect(onMock).toHaveBeenNthCalledWith( + expect(mockOn).toHaveBeenNthCalledWith( 3, 'draw:created', expect.any(Function) ) - expect(onMock).toHaveBeenNthCalledWith( + expect(mockOn).toHaveBeenNthCalledWith( 4, 'draw:edited', expect.any(Function) ) - expect(onMock).toHaveBeenNthCalledWith( + expect(mockOn).toHaveBeenNthCalledWith( 5, 'draw:cancelled', expect.any(Function) ) - expect(onMock).toHaveBeenNthCalledWith( + expect(mockOn).toHaveBeenNthCalledWith( 6, 'interact:markerchange', expect.any(Function) ) - const onDrawReady = onMock.mock.calls[1][1] + const onDrawReady = mockOn.mock.calls[1][1] expect(typeof onDrawReady).toBe('function') // Manually invoke onDrawReady callback @@ -800,20 +794,20 @@ describe('Maps Client JS', () => { * @param {number} [offset] */ function expectToggleButtons(hidden, offset = 0) { - expect(toggleButtonStateMock).toHaveBeenCalledTimes(3 + offset) - expect(toggleButtonStateMock).toHaveBeenNthCalledWith( + expect(mockToggleButtonState).toHaveBeenCalledTimes(3 + offset) + expect(mockToggleButtonState).toHaveBeenNthCalledWith( 1 + offset, 'btnAddPoint', 'hidden', hidden ) - expect(toggleButtonStateMock).toHaveBeenNthCalledWith( + expect(mockToggleButtonState).toHaveBeenNthCalledWith( 2 + offset, 'btnAddPolygon', 'hidden', hidden ) - expect(toggleButtonStateMock).toHaveBeenNthCalledWith( + expect(mockToggleButtonState).toHaveBeenNthCalledWith( 3 + offset, 'btnAddLine', 'hidden', @@ -882,17 +876,17 @@ describe('Maps Client JS', () => { test('initMaps geospatial component initializes without errors when DOM elements are present', () => { initialiseGeospatialMaps() - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(addButtonMock).toHaveBeenCalledTimes(3) - expect(interactPluginEnable).not.toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockAddButton).toHaveBeenCalledTimes(3) + expect(mockInteractPluginEnable).not.toHaveBeenCalled() }) test('initMaps with initial values', () => { initialiseGeospatialMaps() - expect(drawPluginAddFeature).toHaveBeenCalledTimes(2) - expect(addMarkerMock).toHaveBeenCalledOnce() + expect(mockDrawPluginAddFeature).toHaveBeenCalledTimes(2) + expect(mockAddMarker).toHaveBeenCalledOnce() }) test('initMaps with no initial value', () => { @@ -917,19 +911,20 @@ describe('Maps Client JS', () => { initialiseGeospatialMaps() - expect(datasetsMaplibrePlugin).toHaveBeenCalledWith({ - datasets: Array(2).fill(expect.any(Object)) + expect(mockDatasetsMaplibrePlugin).toHaveBeenCalledWith({ + datasets: Array(2).fill(expect.any(Object)), + layerAdapter: expect.any(Object) }) - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(addButtonMock).toHaveBeenCalledTimes(3) - expect(interactPluginEnable).not.toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockAddButton).toHaveBeenCalledTimes(3) + expect(mockInteractPluginEnable).not.toHaveBeenCalled() }) test('drawing created', () => { const { geospatialInput } = initialiseGeospatialMaps() - const onDrawCreated = onMock.mock.calls[2][1] + const onDrawCreated = mockOn.mock.calls[2][1] expect(typeof onDrawCreated).toBe('function') // Manually invoke onDrawCreated callback with a new polygon @@ -1016,7 +1011,7 @@ describe('Maps Client JS', () => { test('drawing edited', () => { const { geospatialInput, listContainer } = initialiseGeospatialMaps() - const onDrawEdited = onMock.mock.calls[3][1] + const onDrawEdited = mockOn.mock.calls[3][1] expect(typeof onDrawEdited).toBe('function') // Manually click the "Change" link to set the _activeFeatureId @@ -1026,7 +1021,7 @@ describe('Maps Client JS', () => { ) stJamesParkChangeLink.click() - expect(drawPluginEditFeature).toHaveBeenCalledWith( + expect(mockDrawPluginEditFeature).toHaveBeenCalledWith( '6d75415d-31e8-4ce7-88f0-621ae3321d6a' ) @@ -1076,7 +1071,7 @@ describe('Maps Client JS', () => { stJamesParkDeleteLink.click() - expect(drawPluginDeleteFeature).toHaveBeenCalledWith( + expect(mockDrawPluginDeleteFeature).toHaveBeenCalledWith( '6d75415d-31e8-4ce7-88f0-621ae3321d6a' ) @@ -1089,7 +1084,7 @@ describe('Maps Client JS', () => { test('drawing cancelled', () => { initialiseGeospatialMaps() - const onDrawCancelled = onMock.mock.calls[4][1] + const onDrawCancelled = mockOn.mock.calls[4][1] expect(typeof onDrawCancelled).toBe('function') // Manually invoke onDrawReady callback (to render the list) @@ -1100,7 +1095,7 @@ describe('Maps Client JS', () => { test('marker added', () => { const { geospatialInput } = initialiseGeospatialMaps() - const interactMarkerChange = onMock.mock.calls[5][1] + const interactMarkerChange = mockOn.mock.calls[5][1] expect(typeof interactMarkerChange).toBe('function') // Manually invoke interactMarkerChange callback with a new point @@ -1110,12 +1105,12 @@ describe('Maps Client JS', () => { interactMarkerChange(newPointFeature) - expect(addMarkerMock).toHaveBeenLastCalledWith( + expect(mockAddMarker).toHaveBeenLastCalledWith( expect.any(String), newPointFeature.coords ) - expect(removeMarkerMock).toHaveBeenCalledExactlyOnceWith('location') - expect(interactPluginDisable).toHaveBeenCalled() + expect(mockRemoveMarker).toHaveBeenCalledExactlyOnceWith('location') + expect(mockInteractPluginDisable).toHaveBeenCalled() expectToggleButtons(false) expect(JSON.parse(geospatialInput.value)).toEqual([ @@ -1139,7 +1134,7 @@ describe('Maps Client JS', () => { test('marker edited', () => { const { geospatialInput, listContainer } = initialiseGeospatialMaps() - const interactMarkerChange = onMock.mock.calls[5][1] + const interactMarkerChange = mockOn.mock.calls[5][1] expect(typeof interactMarkerChange).toBe('function') // Manually click the "Change" link to set the _activeFeatureId @@ -1149,10 +1144,12 @@ describe('Maps Client JS', () => { ) buckinghamPalaceChangeLink.click() - expect(interactPluginSelectFeature).toHaveBeenCalledExactlyOnceWith({ - featureId: '6d67810c-7228-4f71-b6ec-0d16b132fcd7' - }) - expect(interactPluginEnable).toHaveBeenCalledOnce() + expect(mockInteractPluginSelectFeature).toHaveBeenCalledExactlyOnceWith( + { + featureId: '6d67810c-7228-4f71-b6ec-0d16b132fcd7' + } + ) + expect(mockInteractPluginEnable).toHaveBeenCalledOnce() expectToggleButtons(true) // Manually invoke interactMarkerChange callback with a new point @@ -1162,7 +1159,7 @@ describe('Maps Client JS', () => { interactMarkerChange(updatedPointArgs) - expect(addMarkerMock).toHaveBeenLastCalledWith( + expect(mockAddMarker).toHaveBeenLastCalledWith( '6d67810c-7228-4f71-b6ec-0d16b132fcd7', [0, 0] ) @@ -1196,7 +1193,7 @@ describe('Maps Client JS', () => { buckinghamPalaceDeleteLink.click() - expect(removeMarkerMock).toHaveBeenCalledWith( + expect(mockRemoveMarker).toHaveBeenCalledWith( '6d67810c-7228-4f71-b6ec-0d16b132fcd7' ) @@ -1209,13 +1206,13 @@ describe('Maps Client JS', () => { test('action buttons', () => { initialiseGeospatialMaps() - const onMapReady = onMock.mock.calls[5][1] + const onMapReady = mockOn.mock.calls[5][1] expect(typeof onMapReady).toBe('function') - expect(addButtonMock).toHaveBeenCalledTimes(3) - const { onClick: onAddPointClick } = addButtonMock.mock.calls[0][1] - const { onClick: onAddPolygonClick } = addButtonMock.mock.calls[1][1] - const { onClick: onAddLineClick } = addButtonMock.mock.calls[2][1] + expect(mockAddButton).toHaveBeenCalledTimes(3) + const { onClick: onAddPointClick } = mockAddButton.mock.calls[0][1] + const { onClick: onAddPolygonClick } = mockAddButton.mock.calls[1][1] + const { onClick: onAddLineClick } = mockAddButton.mock.calls[2][1] expect(typeof onAddPointClick).toBe('function') expect(typeof onAddPolygonClick).toBe('function') @@ -1224,12 +1221,12 @@ describe('Maps Client JS', () => { // Manually invoke add point button click onAddPointClick() expectToggleButtons(true) - expect(interactPluginEnable).toHaveBeenCalledTimes(1) + expect(mockInteractPluginEnable).toHaveBeenCalledTimes(1) // Manually invoke add polygon button click onAddPolygonClick() expectToggleButtons(true, 3) - expect(drawPluginNewPolygon).toHaveBeenCalledExactlyOnceWith( + expect(mockDrawPluginNewPolygon).toHaveBeenCalledExactlyOnceWith( expect.any(String), expect.any(Object) ) @@ -1237,7 +1234,7 @@ describe('Maps Client JS', () => { // Manually invoke add line button click onAddLineClick() expectToggleButtons(true, 6) - expect(drawPluginNewLine).toHaveBeenCalledExactlyOnceWith( + expect(mockDrawPluginNewLine).toHaveBeenCalledExactlyOnceWith( expect.any(String), expect.any(Object) ) @@ -1371,10 +1368,10 @@ describe('Maps Client JS', () => { test('initMaps with no country boundaries', () => { initialiseGeospatialMaps(false) - expect(interactPlugin).toHaveBeenCalledWith(expect.any(Object)) - expect(addPanelMock).toHaveBeenCalledWith('info', expect.any(Object)) - expect(addButtonMock).toHaveBeenCalledTimes(3) - expect(interactPluginEnable).not.toHaveBeenCalled() + expect(createInteractPlugin).toHaveBeenCalledWith(expect.any(Object)) + expect(mockAddPanel).toHaveBeenCalledWith('info', expect.any(Object)) + expect(mockAddButton).toHaveBeenCalledTimes(3) + expect(mockInteractPluginEnable).not.toHaveBeenCalled() }) }) }) From e4b456e1f4534dc9138f3c0d085ac556de0aa649 Mon Sep 17 00:00:00 2001 From: David Stone Date: Fri, 5 Jun 2026 09:55:10 +0100 Subject: [PATCH 2/2] Remove reverse geocode proxy capability --- src/server/plugins/map/routes/index.js | 38 +------------- src/server/plugins/map/service.js | 13 ----- src/server/plugins/map/service.test.js | 50 ------------------- .../plugins/map/test/__stubs__/nearest.js | 46 ----------------- test/form/map.test.js | 15 +----- 5 files changed, 2 insertions(+), 160 deletions(-) delete mode 100644 src/server/plugins/map/test/__stubs__/nearest.js diff --git a/src/server/plugins/map/routes/index.js b/src/server/plugins/map/routes/index.js index cafb245d5..d885e4e94 100644 --- a/src/server/plugins/map/routes/index.js +++ b/src/server/plugins/map/routes/index.js @@ -6,7 +6,7 @@ import { StatusCodes } from 'http-status-codes' import Joi from 'joi' import { getAccessToken } from '~/src/server/plugins/map/routes/get-os-token.js' -import { find, nearest } from '~/src/server/plugins/map/service.js' +import { find } from '~/src/server/plugins/map/service.js' import { get, request as httpRequest @@ -34,7 +34,6 @@ export function getRoutes(options) { mapProxyRoute(options), tileProxyRoute(options), geocodeProxyRoute(options), - reverseGeocodeProxyRoute(options), getGeospatialCountries() ] } @@ -156,41 +155,6 @@ function geocodeProxyRoute(options) { } } -/** - * Proxies ordnance survey reverse geocode requests from the front end to api.os.uk - * Used to find name from easting and northing points. - * N.B this endpoint is currently not used by the front end but will be soon in "maps V2" - * @param {MapConfiguration} options - the map options - * @returns {ServerRoute} - */ -function reverseGeocodeProxyRoute(options) { - return { - method: 'GET', - path: '/api/reverse-geocode-proxy', - async handler(request, _h) { - const { query } = request - const data = await nearest( - query.easting, - query.northing, - options.ordnanceSurveyApiKey - ) - - return data - }, - options: { - auth: false, - validate: { - query: Joi.object() - .keys({ - easting: Joi.number().required(), - northing: Joi.number().required() - }) - .required() - } - } - } -} - /** * Resource routes to return sprites and glyphs * @returns {ServerRoute} diff --git a/src/server/plugins/map/service.js b/src/server/plugins/map/service.js index e8679225d..52878009d 100644 --- a/src/server/plugins/map/service.js +++ b/src/server/plugins/map/service.js @@ -67,19 +67,6 @@ export async function find(query, apiKey) { return getData(url, endpoint) } -/** - * OS names search nearest by E/N - * @param {number} easting - the easting - * @param {number} northing - the northing - * @param {string} apiKey - the OS api key - */ -export async function nearest(easting, northing, apiKey) { - const endpoint = 'nearest' - const url = `https://api.os.uk/search/names/v1/nearest?key=${apiKey}&point=${easting},${northing}&radius=1000&fq=local_type:Airfield%20local_type:Airport%20local_type:Bus_Station%20local_type:Chemical_Works%20local_type:City%20local_type:Coach_Station%20local_type:Electricity_Distribution%20local_type:Electricity_Production%20local_type:Further_Education%20local_type:Gas_Distribution_or_Storage%20local_type:Hamlet%20local_type:Harbour%20local_type:Helicopter_Station%20local_type:Heliport%20local_type:Higher_or_University_Education%20local_type:Hill_Or_Mountain%20local_type:Hospice%20local_type:Hospital%20local_type:Medical_Care_Accommodation%20local_type:Named_Road%20local_type:Non_State_Primary_Education%20local_type:Non_State_Secondary_Education%20local_type:Other_Settlement%20local_type:Passenger_Ferry_Terminal%20local_type:Port_Consisting_of_Docks_and_Nautical_Berthing%20local_type:Postcode%20local_type:Primary_Education%20local_type:Railway_Station%20local_type:Road_User_Services%20local_type:Secondary_Education%20local_type:Section_Of_Named_Road%20local_type:Section_Of_Numbered_Road%20local_type:Special_Needs_Education%20local_type:Suburban_Area%20local_type:Town%20local_type:Urban_Greenspace%20local_type:Vehicular_Ferry_Terminal%20local_type:Vehicular_Rail_Terminal%20local_type:Village%20local_type:Waterfall%20` - - return getData(url, endpoint) -} - /** * @import { OsNamesFindResponse, OsNamesFindResult } from '~/src/server/plugins/map/types.js' */ diff --git a/src/server/plugins/map/service.test.js b/src/server/plugins/map/service.test.js index 3ddeb617f..b2f9d7729 100644 --- a/src/server/plugins/map/service.test.js +++ b/src/server/plugins/map/service.test.js @@ -2,7 +2,6 @@ import Boom from '@hapi/boom' import * as service from '~/src/server/plugins/map/service.js' import { result as findResult } from '~/src/server/plugins/map/test/__stubs__/find.js' -import { result as nearestResult } from '~/src/server/plugins/map/test/__stubs__/nearest.js' import { getJson } from '~/src/server/services/httpService.js' jest.mock('~/src/server/services/httpService.ts') @@ -88,55 +87,6 @@ describe('Maps service', () => { expect(results).toEqual([]) }) }) - - describe('nearest', () => { - it('should return entries', async () => { - jest.mocked(getJson).mockResolvedValueOnce({ - res: /** @type {IncomingMessage} */ ({ - statusCode: 200, - headers: {} - }), - payload: nearestResult, - error: undefined - }) - - const { results } = await service.nearest(700000, 1300000, 'apikey') - - expect(results).toHaveLength(1) - expect(results.at(0)).toEqual({ - GAZETTEER_ENTRY: { - ID: 'NW26XE', - NAMES_URI: 'http://data.ordnancesurvey.co.uk/id/postcodeunit/NW26XE', - NAME1: 'NW2 6XE', - TYPE: 'other', - LOCAL_TYPE: 'Postcode', - GEOMETRY_X: 523065, - GEOMETRY_Y: 185795, - MOST_DETAIL_VIEW_RES: 3500, - LEAST_DETAIL_VIEW_RES: 18000, - POPULATED_PLACE: 'London', - POPULATED_PLACE_URI: - 'http://data.ordnancesurvey.co.uk/id/4000000074813508', - POPULATED_PLACE_TYPE: - 'http://www.ordnancesurvey.co.uk/xml/codelists/localtype.xml#city', - DISTRICT_BOROUGH: 'Brent', - DISTRICT_BOROUGH_URI: - 'http://data.ordnancesurvey.co.uk/id/7000000000011447', - DISTRICT_BOROUGH_TYPE: - 'http://data.ordnancesurvey.co.uk/ontology/admingeo/LondonBorough', - COUNTY_UNITARY: 'Greater London', - COUNTY_UNITARY_URI: - 'http://data.ordnancesurvey.co.uk/id/7000000000041441', - COUNTY_UNITARY_TYPE: - 'http://data.ordnancesurvey.co.uk/ontology/admingeo/GreaterLondonAuthority', - REGION: 'London', - REGION_URI: 'http://data.ordnancesurvey.co.uk/id/7000000000041428', - COUNTRY: 'England', - COUNTRY_URI: 'http://data.ordnancesurvey.co.uk/id/country/england' - } - }) - }) - }) }) /** diff --git a/src/server/plugins/map/test/__stubs__/nearest.js b/src/server/plugins/map/test/__stubs__/nearest.js deleted file mode 100644 index d5eb86691..000000000 --- a/src/server/plugins/map/test/__stubs__/nearest.js +++ /dev/null @@ -1,46 +0,0 @@ -export const result = { - header: { - uri: 'https://api.os.uk/search/names/v1/nearest?point=523065%2C185795&radius=1000&fq=local_type%3AAirfield%20local_type%3AAirport%20local_type%3ABus_Station%20local_type%3AChemical_Works%20local_type%3ACity%20local_type%3ACoach_Station%20local_type%3AElectricity_Distribution%20local_type%3AElectricity_Production%20local_type%3AFurther_Education%20local_type%3AGas_Distribution_or_Storage%20local_type%3AHamlet%20local_type%3AHarbour%20local_type%3AHelicopter_Station%20local_type%3AHeliport%20local_type%3AHigher_or_University_Education%20local_type%3AHill_Or_Mountain%20local_type%3AHospice%20local_type%3AHospital%20local_type%3AMedical_Care_Accommodation%20local_type%3ANamed_Road%20local_type%3ANon_State_Primary_Education%20local_type%3ANon_State_Secondary_Education%20local_type%3AOther_Settlement%20local_type%3APassenger_Ferry_Terminal%20local_type%3APort_Consisting_of_Docks_and_Nautical_Berthing%20local_type%3APostcode%20local_type%3APrimary_Education%20local_type%3ARailway_Station%20local_type%3ARoad_User_Services%20local_type%3ASecondary_Education%20local_type%3ASection_Of_Named_Road%20local_type%3ASection_Of_Numbered_Road%20local_type%3ASpecial_Needs_Education%20local_type%3ASuburban_Area%20local_type%3ATown%20local_type%3AUrban_Greenspace%20local_type%3AVehicular_Ferry_Terminal%20local_type%3AVehicular_Rail_Terminal%20local_type%3AVillage%20local_type%3AWaterfall%20', - query: 'point=523065,185795 radius=1000', - format: 'JSON', - maxresults: 1, - offset: 0, - totalresults: 1, - filter: - 'fq=local_type:Airfield local_type:Airport local_type:Bus_Station local_type:Chemical_Works local_type:City local_type:Coach_Station local_type:Electricity_Distribution local_type:Electricity_Production local_type:Further_Education local_type:Gas_Distribution_or_Storage local_type:Hamlet local_type:Harbour local_type:Helicopter_Station local_type:Heliport local_type:Higher_or_University_Education local_type:Hill_Or_Mountain local_type:Hospice local_type:Hospital local_type:Medical_Care_Accommodation local_type:Named_Road local_type:Non_State_Primary_Education local_type:Non_State_Secondary_Education local_type:Other_Settlement local_type:Passenger_Ferry_Terminal local_type:Port_Consisting_of_Docks_and_Nautical_Berthing local_type:Postcode local_type:Primary_Education local_type:Railway_Station local_type:Road_User_Services local_type:Secondary_Education local_type:Section_Of_Named_Road local_type:Section_Of_Numbered_Road local_type:Special_Needs_Education local_type:Suburban_Area local_type:Town local_type:Urban_Greenspace local_type:Vehicular_Ferry_Terminal local_type:Vehicular_Rail_Terminal local_type:Village local_type:Waterfall' - }, - results: [ - { - GAZETTEER_ENTRY: { - ID: 'NW26XE', - NAMES_URI: 'http://data.ordnancesurvey.co.uk/id/postcodeunit/NW26XE', - NAME1: 'NW2 6XE', - TYPE: 'other', - LOCAL_TYPE: 'Postcode', - GEOMETRY_X: 523065, - GEOMETRY_Y: 185795, - MOST_DETAIL_VIEW_RES: 3500, - LEAST_DETAIL_VIEW_RES: 18000, - POPULATED_PLACE: 'London', - POPULATED_PLACE_URI: - 'http://data.ordnancesurvey.co.uk/id/4000000074813508', - POPULATED_PLACE_TYPE: - 'http://www.ordnancesurvey.co.uk/xml/codelists/localtype.xml#city', - DISTRICT_BOROUGH: 'Brent', - DISTRICT_BOROUGH_URI: - 'http://data.ordnancesurvey.co.uk/id/7000000000011447', - DISTRICT_BOROUGH_TYPE: - 'http://data.ordnancesurvey.co.uk/ontology/admingeo/LondonBorough', - COUNTY_UNITARY: 'Greater London', - COUNTY_UNITARY_URI: - 'http://data.ordnancesurvey.co.uk/id/7000000000041441', - COUNTY_UNITARY_TYPE: - 'http://data.ordnancesurvey.co.uk/ontology/admingeo/GreaterLondonAuthority', - REGION: 'London', - REGION_URI: 'http://data.ordnancesurvey.co.uk/id/7000000000041428', - COUNTRY: 'England', - COUNTRY_URI: 'http://data.ordnancesurvey.co.uk/id/country/england' - } - } - ] -} diff --git a/test/form/map.test.js b/test/form/map.test.js index 1ab1cdfd5..531cfafc5 100644 --- a/test/form/map.test.js +++ b/test/form/map.test.js @@ -3,9 +3,8 @@ import { StatusCodes } from 'http-status-codes' import { FORM_PREFIX } from '~/src/server/constants.js' import { createServer } from '~/src/server/index.js' import { getAccessToken } from '~/src/server/plugins/map/routes/get-os-token.js' -import { find, nearest } from '~/src/server/plugins/map/service.js' +import { find } from '~/src/server/plugins/map/service.js' import { result as findResult } from '~/src/server/plugins/map/test/__stubs__/find.js' -import { result as nearestResult } from '~/src/server/plugins/map/test/__stubs__/nearest.js' import { get, request } from '~/src/server/services/httpService.js' const basePath = `${FORM_PREFIX}/api` @@ -160,18 +159,6 @@ describe('Map API routes', () => { expect(response.result).toEqual(findResult) }) - it('should get reverse geocode results', async () => { - jest.mocked(nearest).mockResolvedValueOnce(nearestResult) - - const response = await server.inject({ - url: `${basePath}/reverse-geocode-proxy?easting=523065&northing=185795`, - method: 'GET' - }) - - expect(response.statusCode).toBe(StatusCodes.OK) - expect(response.result).toEqual(nearestResult) - }) - it('should get all geojson countries boundaries', async () => { /** * @type {ServerInjectResponse}