diff --git a/x-pack/plugins/maps/public/shared/layers/sources/wms_source/wms_client.js b/x-pack/plugins/maps/public/shared/layers/sources/wms_source/wms_client.js index 22eb4289465f..b8c502858794 100644 --- a/x-pack/plugins/maps/public/shared/layers/sources/wms_source/wms_client.js +++ b/x-pack/plugins/maps/public/shared/layers/sources/wms_source/wms_client.js @@ -147,6 +147,13 @@ function groupCapabilities(list) { return []; } + let maxPathDepth = 0; + list.forEach(({ path }) => { + if (path.length > maxPathDepth) { + maxPathDepth = path.length; + } + }); + let rootCommonPath = list[0].path; for(let listIndex = 1; listIndex < list.length; listIndex++) { if (rootCommonPath.length === 0) { @@ -164,16 +171,37 @@ function groupCapabilities(list) { } } - if (rootCommonPath.length === 0 || list.length === 1) { - return list.map(({ path, value }) => { - return { label: path.join(' - '), value }; - }); + const labelMap = new Map(); + const options = list.map(({ path, value }) => { + const title = path[path.length - 1]; + const hierachyWithTitle = rootCommonPath.length === path.length + ? title // entire path is common, only use title + : path.splice(rootCommonPath.length).join(' - '); + const label = title === value + ? hierachyWithTitle + : `${hierachyWithTitle} (${value})`; + + // labels are used as keys in react elements so uniqueness must be guaranteed + let uniqueLabel; + if (labelMap.has(label)) { + const counter = labelMap.get(label); + const nextCounter = counter + 1; + labelMap.set(label, nextCounter); + uniqueLabel = `${label}:${nextCounter}`; + } else { + labelMap.set(label, 0); + uniqueLabel = label; + } + return { label: uniqueLabel, value }; + }); + + // no common path or all at same depth path + if (rootCommonPath.length === 0 || rootCommonPath.length === maxPathDepth) { + return options; } return [{ label: rootCommonPath.join(' - '), - options: list.map(({ path, value }) => { - return { label: path.splice(rootCommonPath.length).join(' - '), value }; - }) + options }]; } diff --git a/x-pack/plugins/maps/public/shared/layers/sources/wms_source/wms_client.test.js b/x-pack/plugins/maps/public/shared/layers/sources/wms_source/wms_client.test.js index d8f1f977d063..df8eedc998b0 100644 --- a/x-pack/plugins/maps/public/shared/layers/sources/wms_source/wms_client.test.js +++ b/x-pack/plugins/maps/public/shared/layers/sources/wms_source/wms_client.test.js @@ -40,12 +40,12 @@ describe('getCapabilities', () => { }; const capabilities = await wmsClient.getCapabilities(); expect(capabilities.layers).toEqual([ - { label: 'layer1', value: '1' }, - { label: 'layer2', value: '2' } + { label: 'layer1 (1)', value: '1' }, + { label: 'layer2 (2)', value: '2' } ]); expect(capabilities.styles).toEqual([ - { label: 'defaultStyle', value: 'default' }, - { label: 'fancyStyle', value: 'fancy' } + { label: 'defaultStyle (default)', value: 'default' }, + { label: 'fancyStyle (fancy)', value: 'fancy' } ]); }); @@ -97,13 +97,13 @@ describe('getCapabilities', () => { }; const capabilities = await wmsClient.getCapabilities(); expect(capabilities.layers).toEqual([ - { label: 'hierarchyLevel1PathA - hierarchyLevel2 - layer1', value: '1' }, - { label: 'hierarchyLevel1PathA - hierarchyLevel2 - layer2', value: '2' }, - { label: 'hierarchyLevel1PathB - layer3', value: '3' } + { label: 'hierarchyLevel1PathA - hierarchyLevel2 - layer1 (1)', value: '1' }, + { label: 'hierarchyLevel1PathA - hierarchyLevel2 - layer2 (2)', value: '2' }, + { label: 'hierarchyLevel1PathB - layer3 (3)', value: '3' } ]); expect(capabilities.styles).toEqual([ - { label: 'hierarchyLevel1PathA - hierarchyLevel2 - defaultStyle', value: 'default' }, - { label: 'hierarchyLevel1PathB - fancyStyle', value: 'fancy' } + { label: 'hierarchyLevel1PathA - hierarchyLevel2 - defaultStyle (default)', value: 'default' }, + { label: 'hierarchyLevel1PathB - fancyStyle (fancy)', value: 'fancy' } ]); }); @@ -155,8 +155,8 @@ describe('getCapabilities', () => { { label: 'hierarchyLevel1PathA - hierarchyLevel2', options: [ - { label: 'layer1', value: '1' }, - { label: 'layer2', value: '2' }, + { label: 'layer1 (1)', value: '1' }, + { label: 'layer2 (2)', value: '2' }, ] } ]); @@ -164,14 +164,61 @@ describe('getCapabilities', () => { { label: 'hierarchyLevel1PathA - hierarchyLevel2', options: [ - { label: 'defaultStyle', value: 'default' }, - { label: 'fancyStyle', value: 'fancy' }, + { label: 'defaultStyle (default)', value: 'default' }, + { label: 'fancyStyle (fancy)', value: 'fancy' }, ] } ]); }); - it('Should create not group common hierarchy when there is only a single layer', async () => { + it('Should ensure no option labels have name collisions', async () => { + const wmsClient = new WmsClient({ serviceUrl: 'myWMSUrl' }); + wmsClient._fetch = () => { + return { + status: 200, + text: () => { + return ` + + + + mylayer + my_layer + + + + mylayer + my_layer + + + + mylayer + my_layer + + + + + `; + } + }; + }; + const capabilities = await wmsClient.getCapabilities(); + expect(capabilities.layers).toEqual([ + { label: 'mylayer (my_layer)', value: 'my_layer' }, + { label: 'mylayer (my_layer):1', value: 'my_layer' }, + { label: 'mylayer (my_layer):2', value: 'my_layer' }, + ]); + }); + + it('Should not create group common hierarchy when there is only a single layer', async () => { const wmsClient = new WmsClient({ serviceUrl: 'myWMSUrl' }); wmsClient._fetch = () => { return { @@ -192,10 +239,12 @@ describe('getCapabilities', () => { }; const capabilities = await wmsClient.getCapabilities(); expect(capabilities.layers).toEqual([ - { label: 'layer1', value: '1' }, + { label: 'layer1 (1)', value: '1' }, ]); }); +}); +describe('getUrlTemplate', () => { it('Should not overwrite specific query parameters when defined in the url', async () => { const urlWithQuery = 'http://example.com/wms?map=MyMap&format=image/jpeg&service=NotWMS&version=0&request=GetNull&srs=Invalid&transparent=false&width=1024&height=640'; const wmsClient = new WmsClient({ serviceUrl: urlWithQuery });