• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geosolutions-it / MapStore2 / 19710972030

26 Nov 2025 03:38PM UTC coverage: 76.665% (-0.3%) from 76.929%
19710972030

Pull #11119

github

web-flow
Fix maven publish (#11739)
Pull Request #11119: Layer Selection Plugin on ArcGIS, WFS & WMS layers

32272 of 50209 branches covered (64.28%)

3 of 3 new or added lines in 2 files covered. (100.0%)

3018 existing lines in 249 files now uncovered.

40157 of 52380 relevant lines covered (76.66%)

37.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.42
/web/client/api/catalog/WFS.js
1
/*
2
 * Copyright 2020, GeoSolutions Sas.
3
 * All rights reserved.
4
 *
5
 * This source code is licensed under the BSD-style license found in the
6
 * LICENSE file in the root directory of this source tree.
7
 */
8

9
import { cleanAuthParamsFromURL } from '../../utils/SecurityUtils';
10
import { getRecordLinks, extractOGCServicesReferences } from '../../utils/CatalogUtils';
11

12
import { getCapabilities, getCapabilitiesURL } from '../WFS';
13
import {
14
    validate as commonValidate,
15
    testService as commonTestService,
16
    preprocess as commonPreprocess
17
} from './common';
18
import { get, castArray, isEmpty } from 'lodash';
19

20
const searchAndPaginate = (json = {}, startPosition, maxRecords, text) => {
1!
21

22
    const layers = castArray(get(json, '["wfs:WFS_Capabilities"].FeatureTypeList.FeatureType', []));
4✔
23

24
    const filteredLayers = layers
4✔
25
        .map((featureType) => {
26
            const {
27
                Name: name,
28
                Title: title,
29
                Abstract: description,
30
                DefaultSRS: srs,
31
                OtherSRS: OtherSRS = []
19✔
32
            } = featureType;
19✔
33
            // TODO: get operations to identify real URLs from capabilities.
34
            const boundingBox = featureType["ows:WGS84BoundingBox"];
19✔
35
            const sw = boundingBox["ows:LowerCorner"].split(" ");
19✔
36
            const ne = boundingBox["ows:UpperCorner"].split(" ");
19✔
37
            const bounds = {
19✔
38
                minx: parseFloat(sw[0]),
39
                miny: parseFloat(sw[1]),
40
                maxx: parseFloat(ne[0]),
41
                maxy: parseFloat(ne[1])
42
            };
43
            return {
19✔
44
                featureType,
45
                type: "wfs",
46
                url: cleanAuthParamsFromURL(json.url), // Service URL
47
                name,
48
                title,
49
                description,
50
                SRS: [srs, ...OtherSRS],
51
                defaultSRS: srs,
52
                boundingBox: {
53
                    bounds,
54
                    crs: "EPSG:4326"
55
                }
56
            };
57
        })
58
        .filter(({ title = "", name = "", description } = {}) => !text
19!
59
            || title.toLowerCase().indexOf(text.toLowerCase()) !== -1
60
            || name.toLowerCase().indexOf(text.toLowerCase()) !== -1
61
            || description.toLowerCase().indexOf(text.toLowerCase()) !== -1
62
        );
63
    const records = filteredLayers
4✔
64
        .filter((layer, index) => index >= startPosition - 1 && index < startPosition - 1 + maxRecords);
14✔
65
    return {
4✔
66
        numberOfRecordsMatched: filteredLayers.length,
67
        numberOfRecordsReturned: Math.min(maxRecords, records.length),
68
        nextRecord: startPosition + Math.min(maxRecords, filteredLayers.length) + 1,
69
        records
70
    };
71
};
72

73
const recordToLayer = (record, {
1✔
74
    service
75
}) => {
76
    const {
77
        layerOptions
78
    } = service || {};
1!
79
    let security;
80
    if (service?.protectedId) {
1!
UNCOV
81
        security = {sourceId: service?.protectedId, type: "basic"};
×
82
    }
83
    return {
1✔
84
        type: record.type || "wfs",
2✔
85
        search: {
86
            url: record.url,
87
            type: "wfs"
88
        },
89
        security,
90
        url: record.url,
91
        queryable: record.queryable,
92
        visibility: true,
93
        name: record.name,
94
        title: record.title || record.name,
2✔
95
        description: record.description || "",
2✔
96
        bbox: record.boundingBox,
97
        links: getRecordLinks(record),
98
        ...record.layerOptions,
99
        ...layerOptions
100
    };
101
};
102

103
export const getRecords = (url, startPosition, maxRecords, text, info) => {
1✔
104
    return getCapabilities(url, info).then((data) => {
5✔
105
        return searchAndPaginate(data, startPosition, maxRecords, text, info);
4✔
106
    });
107
};
108

109
export const preprocess = commonPreprocess;
1✔
110
export const validate = commonValidate;
1✔
111
export const testService = commonTestService({ parseUrl: getCapabilitiesURL });
1✔
112
export const textSearch = (url, startPosition, maxRecords, text, info) => getRecords(url, startPosition, maxRecords, text, info);
4✔
113
export const getCatalogRecords = ({records} = {}) => {
1!
UNCOV
114
    if (records) {
×
UNCOV
115
        return records.map(record => {
×
UNCOV
116
            const references = [{
×
117
                type: "OGC:WFS-1.1.0-http-get-capabilities",
118
                url: record.url
119
            },
120
            {
121
                type: "OGC:WFS-1.1.0-http-get-feature",
122
                url: record.url
123
            }];
UNCOV
124
            const { wfs: ogcReferences } = extractOGCServicesReferences({ references });
×
UNCOV
125
            return {
×
126
                ...record,
127
                serviceType: 'wfs',
128
                isValid: !!ogcReferences,
129
                references,
130
                ogcReferences
131
            };
132
        });
133
    }
UNCOV
134
    return null;
×
135
};
136

137
/**
138
 * Formulate WFS layer data from record
139
 * and fetch capabilities if needed to add capibilities specific data
140
 * @param {Object} record data obtained from catalog service
141
 * @param {Object} options props specific to wfs
142
 * @returns {Promise} promise that resolves to formulated layer data
143
 */
144
const getLayerData = (record, options) => {
1✔
145
    const layer = recordToLayer(record, options);
1✔
146
    return getRecords(record.url, 1, 1, record.name).then((result)=> {
1✔
UNCOV
147
        const [newRecord] = result?.records ?? [];
×
UNCOV
148
        return isEmpty(newRecord) ? layer : recordToLayer(newRecord, options);
×
149
    }).catch(() => layer);
1✔
150
};
151

152
export const getLayerFromRecord = (record, options, asPromise) => {
1✔
153
    if (options.fetchCapabilities && asPromise) {
1!
154
        return getLayerData(record, options);
1✔
155
    }
UNCOV
156
    const layer = recordToLayer(record, options);
×
UNCOV
157
    return asPromise ? Promise.resolve(layer) : layer;
×
158
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc