[Maps] ensure labels extracted from WMS capabilities are unique (#38311)

* [Maps] ensure labels extracted from WMS capabilities are unique

* clean up

* clean up
This commit is contained in:
Nathan Reese 2019-06-06 20:31:36 -06:00 committed by GitHub
parent 297a895460
commit 76f686bf7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 99 additions and 22 deletions

View file

@ -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
}];
}

View file

@ -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 `
<WMT_MS_Capabilities version="1.1.1">
<Capability>
<Layer>
<Title>mylayer</Title>
<Name>my_layer</Name>
<Style>
<Name>default</Name>
<Title>defaultStyle</Title>
</Style>
</Layer>
<Layer>
<Title>mylayer</Title>
<Name>my_layer</Name>
<Style>
<Name>default</Name>
<Title>defaultStyle</Title>
</Style>
</Layer>
<Layer>
<Title>mylayer</Title>
<Name>my_layer</Name>
<Style>
<Name>default</Name>
<Title>defaultStyle</Title>
</Style>
</Layer>
</Capability>
</WMT_MS_Capabilities>
`;
}
};
};
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 });