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

geosolutions-it / MapStore2 / 19258616339

11 Nov 2025 07:41AM UTC coverage: 76.91% (+0.1%) from 76.761%
19258616339

Pull #11483

github

web-flow
Merge 4fab52f9e into c63877182
Pull Request #11483: Fix #11479 Add validation and support for editing restrictions in attribute table

32172 of 49976 branches covered (64.37%)

134 of 158 new or added lines in 15 files covered. (84.81%)

650 existing lines in 48 files now uncovered.

39990 of 51996 relevant lines covered (76.91%)

37.59 hits per line

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

94.29
/web/client/plugins/featuregrid/hooks/useFeatureValidation.js
1
/*
2
 * Copyright 2025, 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 { useMemo } from 'react';
10
import Ajv from 'ajv';
11
import { applyAllChanges, isPrimaryKeyField } from '../../../utils/FeatureGridUtils';
12

13
const ajv = new Ajv({ allErrors: true });
1✔
14

15
// Cache compiled validators to avoid recompiling on every render
16
const validatorCache = new Map();
1✔
17

18
/**
19
 * Get or compile a validator for the given schema
20
 * @param {object} schema - The JSON schema to validate against
21
 * @returns {function} The compiled AJV validator function
22
 */
23
const getValidator = (schema) => {
1✔
24
    if (!schema) return null;
17✔
25

26
    const key = JSON.stringify(schema);
14✔
27
    if (validatorCache.has(key)) return validatorCache.get(key);
14✔
28
    try {
8✔
29
        const validate = ajv.compile(schema);
8✔
30
        validatorCache.set(key, validate);
8✔
31
        return validate;
8✔
32
    } catch (error) {
NEW
33
        console.error('Error compiling JSON schema validator:', error);
×
NEW
34
        return null;
×
35
    }
36
};
37

38
const useFeatureValidation = ({
1✔
39
    featurePropertiesJSONSchema,
40
    newFeatures,
41
    features,
42
    changes,
43
    primaryKeyAttributes = []
14✔
44
}) => {
45
    const validate = useMemo(() => getValidator(featurePropertiesJSONSchema), [featurePropertiesJSONSchema]);
18✔
46

47
    const allFeatures = useMemo(() => {
18✔
48
        return newFeatures && newFeatures.length > 0
17✔
49
            ? [...newFeatures, ...features]
50
            : features;
51
    }, [newFeatures, features]);
52

53
    const validationErrors = useMemo(() => {
18✔
54
        if (!validate || !featurePropertiesJSONSchema) {
18✔
55
            return {};
3✔
56
        }
57

58
        // Create default null properties
59
        const defaultNullProperties = featurePropertiesJSONSchema?.properties
15✔
60
            ? Object.fromEntries(Object.keys(featurePropertiesJSONSchema.properties).map(key => [key, null]))
21✔
61
            : {};
62

63
        return Object.fromEntries(
15✔
64
            allFeatures
65
                .map((feature) => {
66
                    const { id, properties } = applyAllChanges(feature, changes) || {};
18!
67
                    if (!id) return null;
18✔
68

69
                    const valid = validate({ ...defaultNullProperties, ...properties });
17✔
70
                    if (!valid) {
17✔
71
                        // Filter out primary key errors
72
                        const errors = (validate.errors || []).filter(error => {
12!
73
                            // Extract field name from instancePath (e.g., "/fid" -> "fid")
74
                            const path = error.instancePath || error.dataPath || '';
13!
75
                            const fieldName = path.replace(/^[./]/, '');
13✔
76
                            return !isPrimaryKeyField(fieldName, primaryKeyAttributes);
13✔
77
                        });
78

79
                        // Only include this feature if there are non-primary-key errors
80
                        if (errors.length > 0) {
12✔
81
                            return [id, { errors, changed: !!changes[id] || feature._new }];
11✔
82
                        }
83
                    }
84
                    return null;
6✔
85
                })
86
                .filter(value => value)
18✔
87
        );
88
    }, [validate, allFeatures, changes, featurePropertiesJSONSchema, primaryKeyAttributes]);
89

90
    return validationErrors;
18✔
91
};
92

93
export default useFeatureValidation;
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

© 2026 Coveralls, Inc