From 4334a995881d156f3eb387baebcc08d6bf8abddf Mon Sep 17 00:00:00 2001 From: Etienne Trimaille Date: Mon, 30 Mar 2020 15:57:55 +0200 Subject: [PATCH] use enum in the validation result struct, add tests --- .../metadata/qgslayermetadatavalidator.sip.in | 34 ++++------------- .../qgsprojectservervalidator.sip.in | 38 +++++++++++++++++-- src/app/qgsprojectproperties.cpp | 14 +++---- .../metadata/qgslayermetadatavalidator.cpp | 4 +- src/core/metadata/qgslayermetadatavalidator.h | 35 +++++------------ src/core/qgsprojectservervalidator.cpp | 38 +++++++++++++------ src/core/qgsprojectservervalidator.h | 38 +++++++++++++++++-- .../python/test_qgsprojectservervalidator.py | 35 +++++++++++++++-- 8 files changed, 152 insertions(+), 84 deletions(-) diff --git a/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in b/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in index 2b56b1a3c981..353d88fbc234 100644 --- a/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in +++ b/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in @@ -10,12 +10,13 @@ -class QgsAbstractBaseValidator + +class QgsAbstractMetadataBaseValidator { %Docstring -Abstract base class for validators. +Abstract base class for metadata validators. -.. versionadded:: 3.14 +.. versionadded:: 3.0 %End %TypeHeaderCode @@ -23,9 +24,6 @@ Abstract base class for validators. %End public: - - virtual ~QgsAbstractBaseValidator(); - struct ValidationResult { @@ -40,26 +38,10 @@ Constructor for ValidationResult. QString note; }; -}; - - - -class QgsAbstractMetadataBaseValidator : QgsAbstractBaseValidator -{ -%Docstring -Abstract base class for metadata validators. - -.. versionadded:: 3.0 -%End - -%TypeHeaderCode -#include "qgslayermetadatavalidator.h" -%End - public: virtual ~QgsAbstractMetadataBaseValidator(); - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const = 0; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results /Out/ ) const = 0; %Docstring Validates a ``metadata`` object, and returns ``True`` if the metadata is considered valid. @@ -89,7 +71,7 @@ A validator for the native base QGIS metadata schema definition. Constructor for QgsNativeMetadataBaseValidator. %End - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results /Out/ ) const; }; @@ -114,7 +96,7 @@ A validator for the native QGIS layer metadata schema definition. Constructor for QgsNativeMetadataValidator. %End - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results /Out/ ) const; }; @@ -138,7 +120,7 @@ A validator for the native QGIS project metadata schema definition. Constructor for QgsNativeProjectMetadataValidator. %End - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results /Out/ ) const; }; diff --git a/python/core/auto_generated/qgsprojectservervalidator.sip.in b/python/core/auto_generated/qgsprojectservervalidator.sip.in index a9b4a6856b5e..f9e1eb91fb0b 100644 --- a/python/core/auto_generated/qgsprojectservervalidator.sip.in +++ b/python/core/auto_generated/qgsprojectservervalidator.sip.in @@ -10,7 +10,7 @@ -class QgsProjectServerValidator : QgsAbstractBaseValidator +class QgsProjectServerValidator { %Docstring Project server validator. @@ -25,10 +25,42 @@ Project server validator. QgsProjectServerValidator(); %Docstring -Constructor for :py:class:`QgsNativeMetadataBaseValidator`. +Constructor for QgsProjectServerValidator. %End - bool validate( QgsLayerTree *layerTree, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const; + enum ValidationError + { + DuplicatedNames, + ShortNames, + Encoding + }; + + static QString displayValidationError( QgsProjectServerValidator::ValidationError error ); + + struct ValidationResult + { + + ValidationResult( const QgsProjectServerValidator::ValidationError error, const QVariant &identifier ); +%Docstring +Constructor for ValidationResult. +%End + + QgsProjectServerValidator::ValidationError error; + + QVariant identifier; + }; + + bool validate( QgsLayerTree *layerTree, QList< QgsProjectServerValidator::ValidationResult > &results /Out/ ) const; +%Docstring +Validates a layer tree to avoid some problems on QGIS Server, and returns ``True`` if it's considered valid. +If validation fails, the ``results`` list will be filled with a list of +items describing why the validation failed and what needs to be rectified + +:param layerTree: input layer tree + +:return: - bool + - results: results of the validation +%End }; diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index 695296aaef7b..82b32a5e3d61 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -1906,21 +1906,17 @@ void QgsProjectProperties::pbnWCSLayersDeselectAll_clicked() void QgsProjectProperties::pbnLaunchOWSChecker_clicked() { - QList validationResults; + QList validationResults; QgsProjectServerValidator validator; - bool results = validator.validate( QgisApp::instance()->layerTreeView()->layerTreeModel()->rootGroup(), validationResults ); + bool results = validator.validate( QgsProject::instance()->layerTreeRoot(), validationResults ); QString errors; if ( !results ) { - for ( const QgsAbstractBaseValidator::ValidationResult &result : qgis::as_const( validationResults ) ) + for ( const QgsProjectServerValidator::ValidationResult &result : qgis::as_const( validationResults ) ) { - errors += QLatin1String( "" ) % result.section % QLatin1String( " : " ); - if ( ! result.identifier.isNull() ) - { - errors += QLatin1String( " " ) % result.identifier.toString(); - } - errors += QLatin1String( " : " ) % result.note % QLatin1String( "
" ); + errors += QLatin1String( "" ) % QgsProjectServerValidator::displayValidationError( result.error ) % QLatin1String( " : " ); + errors += result.identifier.toString(); } } else diff --git a/src/core/metadata/qgslayermetadatavalidator.cpp b/src/core/metadata/qgslayermetadatavalidator.cpp index 73a404b8c29f..1708fb4438d7 100644 --- a/src/core/metadata/qgslayermetadatavalidator.cpp +++ b/src/core/metadata/qgslayermetadatavalidator.cpp @@ -23,7 +23,7 @@ // QgsNativeMetadataBaseValidator // -bool QgsNativeMetadataBaseValidator::validate( const QgsAbstractMetadataBase *metadata, QList &results ) const +bool QgsNativeMetadataBaseValidator::validate( const QgsAbstractMetadataBase *metadata, QList &results ) const { results.clear(); if ( !metadata ) @@ -185,7 +185,7 @@ bool QgsNativeMetadataValidator::validate( const QgsAbstractMetadataBase *baseMe // QgsNativeProjectMetadataValidator // -bool QgsNativeProjectMetadataValidator::validate( const QgsAbstractMetadataBase *baseMetadata, QList &results ) const +bool QgsNativeProjectMetadataValidator::validate( const QgsAbstractMetadataBase *baseMetadata, QList &results ) const { results.clear(); diff --git a/src/core/metadata/qgslayermetadatavalidator.h b/src/core/metadata/qgslayermetadatavalidator.h index 02691063b772..de2e8321d239 100644 --- a/src/core/metadata/qgslayermetadatavalidator.h +++ b/src/core/metadata/qgslayermetadatavalidator.h @@ -28,16 +28,15 @@ class QgsLayerMetadata; /** * \ingroup core - * \class QgsAbstractBaseValidator - * \brief Abstract base class for validators. - * \since QGIS 3.14 + * \class QgsAbstractMetadataBaseValidator + * \brief Abstract base class for metadata validators. + * \since QGIS 3.0 */ -class CORE_EXPORT QgsAbstractBaseValidator -{ - public: +class CORE_EXPORT QgsAbstractMetadataBaseValidator +{ - virtual ~QgsAbstractBaseValidator() = default; + public: /** * Contains the parameters describing a metadata validation @@ -69,20 +68,6 @@ class CORE_EXPORT QgsAbstractBaseValidator //! The reason behind the validation failure. QString note; }; -}; - - -/** - * \ingroup core - * \class QgsAbstractMetadataBaseValidator - * \brief Abstract base class for metadata validators. - * \since QGIS 3.0 - */ - -class CORE_EXPORT QgsAbstractMetadataBaseValidator : public QgsAbstractBaseValidator -{ - - public: virtual ~QgsAbstractMetadataBaseValidator() = default; @@ -93,7 +78,7 @@ class CORE_EXPORT QgsAbstractMetadataBaseValidator : public QgsAbstractBaseValid * items describing why the validation failed and what needs to be rectified * to fix the metadata. */ - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const = 0; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results SIP_OUT ) const = 0; }; @@ -114,7 +99,7 @@ class CORE_EXPORT QgsNativeMetadataBaseValidator : public QgsAbstractMetadataBas */ QgsNativeMetadataBaseValidator() = default; - bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const override; + bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results SIP_OUT ) const override; }; @@ -136,7 +121,7 @@ class CORE_EXPORT QgsNativeMetadataValidator : public QgsNativeMetadataBaseValid */ QgsNativeMetadataValidator() = default; - bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const override; + bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results SIP_OUT ) const override; }; @@ -157,7 +142,7 @@ class CORE_EXPORT QgsNativeProjectMetadataValidator : public QgsNativeMetadataBa */ QgsNativeProjectMetadataValidator() = default; - bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const override; + bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results SIP_OUT ) const override; }; diff --git a/src/core/qgsprojectservervalidator.cpp b/src/core/qgsprojectservervalidator.cpp index a10be3441645..6a84a1d85fae 100644 --- a/src/core/qgsprojectservervalidator.cpp +++ b/src/core/qgsprojectservervalidator.cpp @@ -22,6 +22,20 @@ #include "qgsvectorlayer.h" +QString QgsProjectServerValidator::displayValidationError( QgsProjectServerValidator::ValidationError error ) +{ + switch ( error ) + { + case QgsProjectServerValidator::Encoding: + return QObject::tr( "Encoding is not set properly. It shouldn't be 'System'" ); + case QgsProjectServerValidator::ShortNames: + return QObject::tr( "Layer short name needs to be updated" ); + case QgsProjectServerValidator::DuplicatedNames: + return QObject::tr( "Layers/groups have the same name or short name" ); + } + return QString(); +} + void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ) { QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children(); @@ -41,27 +55,27 @@ void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, Q else { QgsLayerTreeLayer *treeLayer = static_cast( treeNode ); - QgsMapLayer *l = treeLayer->layer(); - if ( l ) + QgsMapLayer *layer = treeLayer->layer(); + if ( layer ) { - QString shortName = l->shortName(); + QString shortName = layer->shortName(); if ( shortName.isEmpty() ) - owsNames << l->name(); + owsNames << layer->name(); else owsNames << shortName; - if ( l->type() == QgsMapLayerType::VectorLayer ) + + if ( layer->type() == QgsMapLayerType::VectorLayer ) { - QgsVectorLayer *vl = static_cast( l ); + QgsVectorLayer *vl = static_cast( layer ); if ( vl->dataProvider()->encoding() == QLatin1String( "System" ) ) - encodingMessages << l->name(); + encodingMessages << layer->name(); } } } } } - -bool QgsProjectServerValidator::validate( QgsLayerTree *layerTree, QList &results ) const +bool QgsProjectServerValidator::validate( QgsLayerTree *layerTree, QList &results ) const { results.clear(); bool result = true; @@ -96,19 +110,19 @@ bool QgsProjectServerValidator::validate( QgsLayerTree *layerTree, QList &results SIP_OUT ) const; + bool validate( QgsLayerTree *layerTree, QList< QgsProjectServerValidator::ValidationResult > &results SIP_OUT ) const; private: static void browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ); diff --git a/tests/src/python/test_qgsprojectservervalidator.py b/tests/src/python/test_qgsprojectservervalidator.py index dabbe4dd3f15..4181cf3e37ce 100644 --- a/tests/src/python/test_qgsprojectservervalidator.py +++ b/tests/src/python/test_qgsprojectservervalidator.py @@ -28,19 +28,48 @@ def test_project_server_validator(self): """Test project server validator.""" validator = QgsProjectServerValidator() project = QgsProject() - layer = QgsVectorLayer("Point?field=fldtxt:string", "layer_1", "memory") + layer = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1', 'memory') project.addMapLayers([layer]) valid, results = validator.validate(project.layerTreeRoot()) self.assertTrue(valid) self.assertFalse(results) - layer_1 = QgsVectorLayer("Point?field=fldtxt:string", "layer_1", "memory") + layer_1 = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1', 'memory') project.addMapLayers([layer_1]) valid, results = validator.validate(project.layerTreeRoot()) self.assertFalse(valid) - self.assertEqual(results[0].section, 'Duplicated names') + self.assertEqual(1, len(results)) + self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) + + layer_1.setShortName('layer_1_invalid_#') + valid, results = validator.validate(project.layerTreeRoot()) + self.assertFalse(valid) + self.assertEqual(1, len(results)) + self.assertEqual(QgsProjectServerValidator.ShortNames, results[0].error) + + layer_1.setShortName('layer_1') # Same short name as the first layer name + valid, results = validator.validate(project.layerTreeRoot()) + self.assertFalse(valid) + self.assertEqual(1, len(results)) + self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) + + layer_1.setShortName('layer_1_bis') + valid, results = validator.validate(project.layerTreeRoot()) + self.assertTrue(valid) + self.assertEqual(0, len(results)) + + group = project.layerTreeRoot().addGroup('layer_1') + valid, results = validator.validate(project.layerTreeRoot()) + self.assertFalse(valid) + self.assertEqual(1, len(results)) + self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) + + group.setCustomProperty('wmsShortName', 'my_group1') + valid, results = validator.validate(project.layerTreeRoot()) + self.assertTrue(valid) + self.assertEqual(0, len(results)) if __name__ == '__main__':