From c8349a136a1f60d05c1e8621495a0d48a41b429c Mon Sep 17 00:00:00 2001 From: Olivia Guyot Date: Mon, 31 Jul 2023 12:46:19 +0200 Subject: [PATCH] fix(map): remove SERVICE & REQUEST params from wms url If these params are given to OL for the WMS layer then they will most likely cause an error. Added a url utility to remove them in a case-insensitive way. --- .../lib/map-view/map-view.component.spec.ts | 29 ++++++++++++++++++- .../src/lib/map-view/map-view.component.ts | 5 ++-- libs/util/shared/src/lib/utils/index.ts | 1 + libs/util/shared/src/lib/utils/url.spec.ts | 14 +++++++++ libs/util/shared/src/lib/utils/url.ts | 20 +++++++++++++ tsconfig.base.json | 2 +- 6 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 libs/util/shared/src/lib/utils/url.spec.ts create mode 100644 libs/util/shared/src/lib/utils/url.ts diff --git a/libs/feature/record/src/lib/map-view/map-view.component.spec.ts b/libs/feature/record/src/lib/map-view/map-view.component.spec.ts index aa404174d4..426e98fcb2 100644 --- a/libs/feature/record/src/lib/map-view/map-view.component.spec.ts +++ b/libs/feature/record/src/lib/map-view/map-view.component.spec.ts @@ -135,7 +135,7 @@ class OpenLayersMapMock { } } -class InteractionsMock implements Collection {} +class InteractionsMock extends Collection {} class mapManagerMock { map = new OpenLayersMapMock() @@ -743,6 +743,33 @@ describe('MapViewComponent', () => { }) }) }) + + describe('WMS link containing REQUEST & SERVICE params', () => { + beforeEach(() => { + mdViewFacade.mapApiLinks$.next([ + { + url: 'http://abcd.com/wxs/?request=GetCapabilities&a=2&Service=wms', + name: 'layer', + protocol: 'OGC:WMS', + type: MetadataLinkType.WMS, + }, + ]) + mdViewFacade.geoDataLinks$.next([]) + fixture.detectChanges() + }) + it('emits a map context with WMS urls cleaned of unneeded parameters', () => { + expect(mapComponent.context).toEqual({ + layers: [ + { + url: 'http://abcd.com/wxs/?a=2', + name: 'layer', + type: 'wms', + }, + ], + view: expect.any(Object), + }) + }) + }) }) describe('prioritizePageScroll', () => { diff --git a/libs/feature/record/src/lib/map-view/map-view.component.ts b/libs/feature/record/src/lib/map-view/map-view.component.ts index 570064e430..fb13870590 100644 --- a/libs/feature/record/src/lib/map-view/map-view.component.ts +++ b/libs/feature/record/src/lib/map-view/map-view.component.ts @@ -42,6 +42,7 @@ import { } from 'rxjs/operators' import { MdViewFacade } from '../state/mdview.facade' import { DataService } from '@geonetwork-ui/feature/dataviz' +import { removeSearchParams } from '@geonetwork-ui/util/shared' @Component({ selector: 'gn-ui-map-view', @@ -167,7 +168,7 @@ export class MapViewComponent implements OnInit, OnDestroy { getLayerFromLink(link: MetadataLink): Observable { if (link.type === MetadataLinkType.WMS) { return of({ - url: link.url, + url: removeSearchParams(link.url, ['request', 'service']), type: MapContextLayerTypeEnum.WMS, name: link.name, }) @@ -190,7 +191,7 @@ export class MapViewComponent implements OnInit, OnDestroy { })) ) } - return throwError('protocol not supported') + return throwError(() => 'protocol not supported') } selectLinkToDisplay(link: number) { diff --git a/libs/util/shared/src/lib/utils/index.ts b/libs/util/shared/src/lib/utils/index.ts index af7e2f398c..6e8eca5ea2 100644 --- a/libs/util/shared/src/lib/utils/index.ts +++ b/libs/util/shared/src/lib/utils/index.ts @@ -3,3 +3,4 @@ export * from './strip-html' export * from './freeze' export * from './geojson' export * from './atomic-operations' +export * from './url' diff --git a/libs/util/shared/src/lib/utils/url.spec.ts b/libs/util/shared/src/lib/utils/url.spec.ts new file mode 100644 index 0000000000..543962ef52 --- /dev/null +++ b/libs/util/shared/src/lib/utils/url.spec.ts @@ -0,0 +1,14 @@ +import { removeSearchParams } from './url' + +describe('URL utils', () => { + describe('removeSearchParams', () => { + it('removes given search params in a case insensitive way', () => { + expect( + removeSearchParams( + 'http://my.org/abc/?arg0=1234&arg1=aaa&Arg1=111&ARG2=&aRG3=fff&arg4=5678', + ['ARG1', 'arg2', 'arg3'] + ) + ).toEqual('http://my.org/abc/?arg0=1234&arg4=5678') + }) + }) +}) diff --git a/libs/util/shared/src/lib/utils/url.ts b/libs/util/shared/src/lib/utils/url.ts new file mode 100644 index 0000000000..8a5ee6c1de --- /dev/null +++ b/libs/util/shared/src/lib/utils/url.ts @@ -0,0 +1,20 @@ +/** + * Removes the given search params from the URL completely; this is case-insensitive + * @param url + * @param searchParams + */ +export function removeSearchParams( + url: string, + searchParams: string[] +): string { + const toDelete = [] + const urlObj = new URL(url, window.location.toString()) + const keysLower = searchParams.map((p) => p.toLowerCase()) + for (const param of urlObj.searchParams.keys()) { + if (keysLower.indexOf(param.toLowerCase()) > -1) { + toDelete.push(param) + } + } + toDelete.map((param) => urlObj.searchParams.delete(param)) + return urlObj.toString() +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 4779b4035f..2e284c8548 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -10,7 +10,7 @@ "importHelpers": true, "target": "es2020", "module": "esnext", - "lib": ["es2019", "dom"], + "lib": ["es2019", "dom", "dom.iterable"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".",