From 23715aa24b835a271a55e1f2261a9756a2c24769 Mon Sep 17 00:00:00 2001 From: Etienne Trimaille Date: Fri, 27 Mar 2020 19:41:49 +0100 Subject: [PATCH 1/3] port the OWS validation to its own class and sipify --- .../qgsprojectservervalidator.sip.in | 46 ++++++++ python/core/core_auto.sip | 1 + src/app/qgsprojectproperties.cpp | 91 +--------------- src/app/qgsprojectproperties.h | 2 - src/core/CMakeLists.txt | 2 + src/core/qgsprojectservervalidator.cpp | 102 ++++++++++++++++++ src/core/qgsprojectservervalidator.h | 34 ++++++ 7 files changed, 187 insertions(+), 91 deletions(-) create mode 100644 python/core/auto_generated/qgsprojectservervalidator.sip.in create mode 100644 src/core/qgsprojectservervalidator.cpp create mode 100644 src/core/qgsprojectservervalidator.h diff --git a/python/core/auto_generated/qgsprojectservervalidator.sip.in b/python/core/auto_generated/qgsprojectservervalidator.sip.in new file mode 100644 index 000000000000..d6caa6045f26 --- /dev/null +++ b/python/core/auto_generated/qgsprojectservervalidator.sip.in @@ -0,0 +1,46 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/qgsprojectservervalidator.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + +class QgsProjectServerValidator +{ +%Docstring +Project server validator. + +.. versionadded:: 3.14 +%End + +%TypeHeaderCode +#include "qgsprojectservervalidator.h" +%End + public: + + static void checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ); +%Docstring +Recursive function to check a layer tree group. +The function will collect OWS names and encoding for each layers. + +.. versionadded:: 3.14 +%End + + static QString projectStatusHtml( QgsLayerTree *layerTree ); +%Docstring +Check a layer tree. + +.. versionadded:: 3.14 +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/core/qgsprojectservervalidator.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index 48aeaae8ee77..210cb36c3947 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -154,6 +154,7 @@ %Include auto_generated/qgsprojectdisplaysettings.sip %Include auto_generated/qgsprojectfiletransform.sip %Include auto_generated/qgsprojectproperty.sip +%Include auto_generated/qgsprojectservervalidator.sip %Include auto_generated/qgsprojectstorage.sip %Include auto_generated/qgsprojectstorageregistry.sip %Include auto_generated/qgsprojecttimesettings.sip diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index 87319c8f6a47..de5cbf6312f2 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -63,6 +63,7 @@ #include "qgsmessagelog.h" #include "qgslayercapabilitiesmodel.h" #include "qgsexpressioncontextutils.h" +#include "qgsprojectservervalidator.h" #include "qgsprojectstorage.h" #include "qgsprojectstorageregistry.h" #include "qgsprojectviewsettings.h" @@ -1908,57 +1909,7 @@ void QgsProjectProperties::pbnLaunchOWSChecker_clicked() QString myStyle = QgsApplication::reportStyleSheet(); teOWSChecker->clear(); teOWSChecker->document()->setDefaultStyleSheet( myStyle ); - teOWSChecker->setHtml( "

" + tr( "Start checking QGIS Server" ) + "

" ); - - QStringList owsNames, encodingMessages; - checkOWS( QgisApp::instance()->layerTreeView()->layerTreeModel()->rootGroup(), owsNames, encodingMessages ); - - QStringList duplicateNames, regExpMessages; - QRegExp snRegExp = QgsApplication::shortNameRegExp(); - const auto constOwsNames = owsNames; - for ( const QString &name : constOwsNames ) - { - if ( !snRegExp.exactMatch( name ) ) - regExpMessages << tr( "Use short name for \"%1\"" ).arg( name ); - if ( duplicateNames.contains( name ) ) - continue; - if ( owsNames.count( name ) > 1 ) - duplicateNames << name; - } - - if ( !duplicateNames.empty() ) - { - QString nameMessage = "

" + tr( "Some layers and groups have the same name or short name" ) + "

"; - nameMessage += "

" + tr( "Duplicate names:" ) + "

"; - nameMessage += duplicateNames.join( QStringLiteral( "
  • " ) ) + "
  • "; - teOWSChecker->setHtml( teOWSChecker->toHtml() + nameMessage ); - } - else - { - teOWSChecker->setHtml( teOWSChecker->toHtml() + "

    " + tr( "All names and short names of layer and group are unique" ) + "

    " ); - } - - if ( !regExpMessages.empty() ) - { - QString encodingMessage = "

    " + tr( "Some layer short names have to be updated:" ) + "

    "; - teOWSChecker->setHtml( teOWSChecker->toHtml() + encodingMessage ); - } - else - { - teOWSChecker->setHtml( teOWSChecker->toHtml() + "

    " + tr( "All layer short names are well formed" ) + "

    " ); - } - - if ( !encodingMessages.empty() ) - { - QString encodingMessage = "

    " + tr( "Some layer encodings are not set:" ) + "

    "; - teOWSChecker->setHtml( teOWSChecker->toHtml() + encodingMessage ); - } - else - { - teOWSChecker->setHtml( teOWSChecker->toHtml() + "

    " + tr( "All layer encodings are set" ) + "

    " ); - } - - teOWSChecker->setHtml( teOWSChecker->toHtml() + "

    " + tr( "Start checking QGIS Server" ) + "

    " ); + teOWSChecker->setHtml( QgsProjectServerValidator::projectStatusHtml( QgisApp::instance()->layerTreeView()->layerTreeModel()->rootGroup() ) ); } void QgsProjectProperties::pbnAddScale_clicked() @@ -2321,44 +2272,6 @@ void QgsProjectProperties::addWmtsGrid( const QString &crsStr ) twWmtsGrids->blockSignals( false ); } -void QgsProjectProperties::checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ) -{ - QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children(); - for ( int i = 0; i < treeGroupChildren.size(); ++i ) - { - QgsLayerTreeNode *treeNode = treeGroupChildren.at( i ); - if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup ) - { - QgsLayerTreeGroup *treeGroupChild = static_cast( treeNode ); - QString shortName = treeGroupChild->customProperty( QStringLiteral( "wmsShortName" ) ).toString(); - if ( shortName.isEmpty() ) - owsNames << treeGroupChild->name(); - else - owsNames << shortName; - checkOWS( treeGroupChild, owsNames, encodingMessages ); - } - else - { - QgsLayerTreeLayer *treeLayer = static_cast( treeNode ); - QgsMapLayer *l = treeLayer->layer(); - if ( l ) - { - QString shortName = l->shortName(); - if ( shortName.isEmpty() ) - owsNames << l->name(); - else - owsNames << shortName; - if ( l->type() == QgsMapLayerType::VectorLayer ) - { - QgsVectorLayer *vl = static_cast( l ); - if ( vl->dataProvider()->encoding() == QLatin1String( "System" ) ) - encodingMessages << tr( "Update layer \"%1\" encoding" ).arg( l->name() ); - } - } - } - } -} - void QgsProjectProperties::populateEllipsoidList() { // diff --git a/src/app/qgsprojectproperties.h b/src/app/qgsprojectproperties.h index b7457dd92743..ed55624131f9 100644 --- a/src/app/qgsprojectproperties.h +++ b/src/app/qgsprojectproperties.h @@ -251,8 +251,6 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui: void populateWmtsTree( const QgsLayerTreeGroup *treeGroup, QgsTreeWidgetItem *treeItem ); //! add WMTS Grid definition based on CRS void addWmtsGrid( const QString &crsStr ); - //! Check OWS configuration - void checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ); //! Populates list with ellipsoids from Sqlite3 db void populateEllipsoidList(); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f49ca6e9f7d9..30df1f4ef5fb 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -346,6 +346,7 @@ SET(QGIS_CORE_SRCS qgssnappingconfig.cpp qgsprojectdisplaysettings.cpp qgsprojectproperty.cpp + qgsprojectservervalidator.cpp qgsprojectstorage.cpp qgsprojectstorageregistry.cpp qgsprojecttimesettings.cpp @@ -868,6 +869,7 @@ SET(QGIS_CORE_HDRS qgsprojectdisplaysettings.h qgsprojectfiletransform.h qgsprojectproperty.h + qgsprojectservervalidator.h qgsprojectstorage.h qgsprojectstorageregistry.h qgsprojecttimesettings.h diff --git a/src/core/qgsprojectservervalidator.cpp b/src/core/qgsprojectservervalidator.cpp new file mode 100644 index 000000000000..51e9e96cd76b --- /dev/null +++ b/src/core/qgsprojectservervalidator.cpp @@ -0,0 +1,102 @@ +#include "qgsapplication.h" +#include "qgslayertreelayer.h" +#include "qgsprojectservervalidator.h" +#include "qgsvectorlayer.h" + + +void QgsProjectServerValidator::checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ) +{ + QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children(); + for ( int i = 0; i < treeGroupChildren.size(); ++i ) + { + QgsLayerTreeNode *treeNode = treeGroupChildren.at( i ); + if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup ) + { + QgsLayerTreeGroup *treeGroupChild = static_cast( treeNode ); + QString shortName = treeGroupChild->customProperty( QStringLiteral( "wmsShortName" ) ).toString(); + if ( shortName.isEmpty() ) + owsNames << treeGroupChild->name(); + else + owsNames << shortName; + checkOWS( treeGroupChild, owsNames, encodingMessages ); + } + else + { + QgsLayerTreeLayer *treeLayer = static_cast( treeNode ); + QgsMapLayer *l = treeLayer->layer(); + if ( l ) + { + QString shortName = l->shortName(); + if ( shortName.isEmpty() ) + owsNames << l->name(); + else + owsNames << shortName; + if ( l->type() == QgsMapLayerType::VectorLayer ) + { + QgsVectorLayer *vl = static_cast( l ); + if ( vl->dataProvider()->encoding() == QLatin1String( "System" ) ) + encodingMessages << QObject::tr( "Update layer \"%1\" encoding" ).arg( l->name() ); + } + } + } + } +} + + +QString QgsProjectServerValidator::projectStatusHtml( QgsLayerTree *layerTree ) +{ + + QString html = QStringLiteral( "

    " ) + QObject::tr( "Start checking QGIS Server" ) + QStringLiteral( "

    " ); + + QStringList owsNames, encodingMessages; + checkOWS( layerTree, owsNames, encodingMessages ); + + QStringList duplicateNames, regExpMessages; + QRegExp snRegExp = QgsApplication::shortNameRegExp(); + const auto constOwsNames = owsNames; + for ( const QString &name : constOwsNames ) + { + if ( !snRegExp.exactMatch( name ) ) + regExpMessages << QObject::tr( "Use short name for \"%1\"" ).arg( name ); + if ( duplicateNames.contains( name ) ) + continue; + if ( owsNames.count( name ) > 1 ) + duplicateNames << name; + } + + if ( !duplicateNames.empty() ) + { + QString nameMessage = QStringLiteral( "

    " ) + QObject::tr( "Some layers and groups have the same name or short name" ) + QStringLiteral( "

    " ); + nameMessage += "

    " + QObject::tr( "Duplicate names:" ) + "

    "; + nameMessage += duplicateNames.join( QStringLiteral( "
  • " ) ) + QStringLiteral( "
  • " ); + html += nameMessage; + } + else + { + html += QStringLiteral( "

    " ) + QObject::tr( "All names and short names of layer and group are unique" ) + QStringLiteral( "

    " ); + } + + if ( !regExpMessages.empty() ) + { + html += QStringLiteral( "

    " ) + QObject::tr( "Some layer short names have to be updated:" ) + QStringLiteral( "

    • " ); + html += regExpMessages.join( QStringLiteral( "
    • " ) ); + html += QStringLiteral( "
    " ); + } + else + { + html += QStringLiteral( "

    " ) + QObject::tr( "All layer short names are well formed" ) + QStringLiteral( "

    " ); + } + + if ( !encodingMessages.empty() ) + { + html += QStringLiteral( "

    " ) + QObject::tr( "Some layer encodings are not set:" ) + QStringLiteral( "

    • " ); + html += encodingMessages.join( QStringLiteral( "
    • " ) ); + html += QStringLiteral( "
    " ); + } + else + { + html += QStringLiteral( "

    " ) + QObject::tr( "All layer encodings are set" ) + QStringLiteral( "

    " ); + } + + return html; +} diff --git a/src/core/qgsprojectservervalidator.h b/src/core/qgsprojectservervalidator.h new file mode 100644 index 000000000000..8ed51f877ee8 --- /dev/null +++ b/src/core/qgsprojectservervalidator.h @@ -0,0 +1,34 @@ +#include "qgis_core.h" +#include "qgslayertreegroup.h" +#include "qgslayertree.h" + +#ifndef QGSPROJECTSERVERVALIDATOR_H +#define QGSPROJECTSERVERVALIDATOR_H + +/** + * \ingroup core + * \class QgsProjectServerValidator + * \brief Project server validator. + * \since QGIS 3.14 + */ +class CORE_EXPORT QgsProjectServerValidator +{ + + public: + + /** + * Recursive function to check a layer tree group. + * The function will collect OWS names and encoding for each layers. + * \since QGIS 3.14 + */ + static void checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ); + + /** + * Check a layer tree. + * \since QGIS 3.14 + */ + static QString projectStatusHtml( QgsLayerTree *layerTree ); + +}; + +#endif // QGSPROJECTSERVERVALIDATOR_H From f2cbe042cad1eac4b8c3a39f8eac4f566ca9e59a Mon Sep 17 00:00:00 2001 From: Etienne Trimaille Date: Sat, 28 Mar 2020 08:24:15 +0100 Subject: [PATCH 2/3] use the QgsAbstractValidator for validating the project in the server context --- .../metadata/qgslayermetadatavalidator.sip.in | 34 +++++++-- .../qgsprojectservervalidator.sip.in | 19 ++--- src/app/qgsprojectproperties.cpp | 25 ++++++- .../metadata/qgslayermetadatavalidator.cpp | 4 +- src/core/metadata/qgslayermetadatavalidator.h | 35 ++++++--- src/core/qgsprojectservervalidator.cpp | 73 +++++++++++-------- src/core/qgsprojectservervalidator.h | 43 ++++++++--- tests/src/python/CMakeLists.txt | 1 + .../python/test_qgsprojectservervalidator.py | 47 ++++++++++++ 9 files changed, 209 insertions(+), 72 deletions(-) create mode 100644 tests/src/python/test_qgsprojectservervalidator.py diff --git a/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in b/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in index 353d88fbc234..2b56b1a3c981 100644 --- a/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in +++ b/python/core/auto_generated/metadata/qgslayermetadatavalidator.sip.in @@ -10,13 +10,12 @@ - -class QgsAbstractMetadataBaseValidator +class QgsAbstractBaseValidator { %Docstring -Abstract base class for metadata validators. +Abstract base class for validators. -.. versionadded:: 3.0 +.. versionadded:: 3.14 %End %TypeHeaderCode @@ -24,6 +23,9 @@ Abstract base class for metadata validators. %End public: + + virtual ~QgsAbstractBaseValidator(); + struct ValidationResult { @@ -38,10 +40,26 @@ 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< QgsAbstractMetadataBaseValidator::ValidationResult > &results /Out/ ) const = 0; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const = 0; %Docstring Validates a ``metadata`` object, and returns ``True`` if the metadata is considered valid. @@ -71,7 +89,7 @@ A validator for the native base QGIS metadata schema definition. Constructor for QgsNativeMetadataBaseValidator. %End - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results /Out/ ) const; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const; }; @@ -96,7 +114,7 @@ A validator for the native QGIS layer metadata schema definition. Constructor for QgsNativeMetadataValidator. %End - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results /Out/ ) const; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const; }; @@ -120,7 +138,7 @@ A validator for the native QGIS project metadata schema definition. Constructor for QgsNativeProjectMetadataValidator. %End - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results /Out/ ) const; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const; }; diff --git a/python/core/auto_generated/qgsprojectservervalidator.sip.in b/python/core/auto_generated/qgsprojectservervalidator.sip.in index d6caa6045f26..a9b4a6856b5e 100644 --- a/python/core/auto_generated/qgsprojectservervalidator.sip.in +++ b/python/core/auto_generated/qgsprojectservervalidator.sip.in @@ -7,7 +7,10 @@ ************************************************************************/ -class QgsProjectServerValidator + + + +class QgsProjectServerValidator : QgsAbstractBaseValidator { %Docstring Project server validator. @@ -20,20 +23,12 @@ Project server validator. %End public: - static void checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ); + QgsProjectServerValidator(); %Docstring -Recursive function to check a layer tree group. -The function will collect OWS names and encoding for each layers. - -.. versionadded:: 3.14 +Constructor for :py:class:`QgsNativeMetadataBaseValidator`. %End - static QString projectStatusHtml( QgsLayerTree *layerTree ); -%Docstring -Check a layer tree. - -.. versionadded:: 3.14 -%End + bool validate( QgsLayerTree *layerTree, QList< QgsAbstractBaseValidator::ValidationResult > &results /Out/ ) const; }; diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index de5cbf6312f2..695296aaef7b 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -1906,10 +1906,33 @@ void QgsProjectProperties::pbnWCSLayersDeselectAll_clicked() void QgsProjectProperties::pbnLaunchOWSChecker_clicked() { + QList validationResults; + QgsProjectServerValidator validator; + bool results = validator.validate( QgisApp::instance()->layerTreeView()->layerTreeModel()->rootGroup(), validationResults ); + + QString errors; + if ( !results ) + { + for ( const QgsAbstractBaseValidator::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( "
    " ); + } + } + else + { + errors = QString( tr( "Ok, it seems valid." ) ); + } + QString myStyle = QgsApplication::reportStyleSheet(); + myStyle.append( QStringLiteral( "body { margin: 10px; }\n " ) ); teOWSChecker->clear(); teOWSChecker->document()->setDefaultStyleSheet( myStyle ); - teOWSChecker->setHtml( QgsProjectServerValidator::projectStatusHtml( QgisApp::instance()->layerTreeView()->layerTreeModel()->rootGroup() ) ); + teOWSChecker->setHtml( errors ); } void QgsProjectProperties::pbnAddScale_clicked() diff --git a/src/core/metadata/qgslayermetadatavalidator.cpp b/src/core/metadata/qgslayermetadatavalidator.cpp index 1708fb4438d7..73a404b8c29f 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 de2e8321d239..02691063b772 100644 --- a/src/core/metadata/qgslayermetadatavalidator.h +++ b/src/core/metadata/qgslayermetadatavalidator.h @@ -28,16 +28,17 @@ class QgsLayerMetadata; /** * \ingroup core - * \class QgsAbstractMetadataBaseValidator - * \brief Abstract base class for metadata validators. - * \since QGIS 3.0 + * \class QgsAbstractBaseValidator + * \brief Abstract base class for validators. + * \since QGIS 3.14 */ - -class CORE_EXPORT QgsAbstractMetadataBaseValidator +class CORE_EXPORT QgsAbstractBaseValidator { - public: + + virtual ~QgsAbstractBaseValidator() = default; + /** * Contains the parameters describing a metadata validation * failure. @@ -68,6 +69,20 @@ class CORE_EXPORT QgsAbstractMetadataBaseValidator //! 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; @@ -78,7 +93,7 @@ class CORE_EXPORT QgsAbstractMetadataBaseValidator * items describing why the validation failed and what needs to be rectified * to fix the metadata. */ - virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results SIP_OUT ) const = 0; + virtual bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const = 0; }; @@ -99,7 +114,7 @@ class CORE_EXPORT QgsNativeMetadataBaseValidator : public QgsAbstractMetadataBas */ QgsNativeMetadataBaseValidator() = default; - bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results SIP_OUT ) const override; + bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const override; }; @@ -121,7 +136,7 @@ class CORE_EXPORT QgsNativeMetadataValidator : public QgsNativeMetadataBaseValid */ QgsNativeMetadataValidator() = default; - bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results SIP_OUT ) const override; + bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const override; }; @@ -142,7 +157,7 @@ class CORE_EXPORT QgsNativeProjectMetadataValidator : public QgsNativeMetadataBa */ QgsNativeProjectMetadataValidator() = default; - bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractMetadataBaseValidator::ValidationResult > &results SIP_OUT ) const override; + bool validate( const QgsAbstractMetadataBase *metadata, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const override; }; diff --git a/src/core/qgsprojectservervalidator.cpp b/src/core/qgsprojectservervalidator.cpp index 51e9e96cd76b..a10be3441645 100644 --- a/src/core/qgsprojectservervalidator.cpp +++ b/src/core/qgsprojectservervalidator.cpp @@ -1,10 +1,28 @@ +/*************************************************************************** + qgsprojectservervalidator.cpp + --------------------------- + begin : March 2020 + copyright : (C) 2020 by Etienne Trimaille + email : etienne dot trimaille at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + #include "qgsapplication.h" #include "qgslayertreelayer.h" #include "qgsprojectservervalidator.h" #include "qgsvectorlayer.h" -void QgsProjectServerValidator::checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ) +void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ) { QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children(); for ( int i = 0; i < treeGroupChildren.size(); ++i ) @@ -18,7 +36,7 @@ void QgsProjectServerValidator::checkOWS( QgsLayerTreeGroup *treeGroup, QStringL owsNames << treeGroupChild->name(); else owsNames << shortName; - checkOWS( treeGroupChild, owsNames, encodingMessages ); + browseLayerTree( treeGroupChild, owsNames, encodingMessages ); } else { @@ -35,7 +53,7 @@ void QgsProjectServerValidator::checkOWS( QgsLayerTreeGroup *treeGroup, QStringL { QgsVectorLayer *vl = static_cast( l ); if ( vl->dataProvider()->encoding() == QLatin1String( "System" ) ) - encodingMessages << QObject::tr( "Update layer \"%1\" encoding" ).arg( l->name() ); + encodingMessages << l->name(); } } } @@ -43,13 +61,16 @@ void QgsProjectServerValidator::checkOWS( QgsLayerTreeGroup *treeGroup, QStringL } -QString QgsProjectServerValidator::projectStatusHtml( QgsLayerTree *layerTree ) +bool QgsProjectServerValidator::validate( QgsLayerTree *layerTree, QList &results ) const { + results.clear(); + bool result = true; - QString html = QStringLiteral( "

    " ) + QObject::tr( "Start checking QGIS Server" ) + QStringLiteral( "

    " ); + if ( !layerTree ) + return false; QStringList owsNames, encodingMessages; - checkOWS( layerTree, owsNames, encodingMessages ); + browseLayerTree( layerTree, owsNames, encodingMessages ); QStringList duplicateNames, regExpMessages; QRegExp snRegExp = QgsApplication::shortNameRegExp(); @@ -57,46 +78,38 @@ QString QgsProjectServerValidator::projectStatusHtml( QgsLayerTree *layerTree ) for ( const QString &name : constOwsNames ) { if ( !snRegExp.exactMatch( name ) ) - regExpMessages << QObject::tr( "Use short name for \"%1\"" ).arg( name ); + { + regExpMessages << name; + } + if ( duplicateNames.contains( name ) ) + { continue; + } + if ( owsNames.count( name ) > 1 ) + { duplicateNames << name; + } } if ( !duplicateNames.empty() ) { - QString nameMessage = QStringLiteral( "

    " ) + QObject::tr( "Some layers and groups have the same name or short name" ) + QStringLiteral( "

    " ); - nameMessage += "

    " + QObject::tr( "Duplicate names:" ) + "

    "; - nameMessage += duplicateNames.join( QStringLiteral( "
  • " ) ) + QStringLiteral( "
  • " ); - html += nameMessage; - } - else - { - html += QStringLiteral( "

    " ) + QObject::tr( "All names and short names of layer and group are unique" ) + QStringLiteral( "

    " ); + result = false; + results << ValidationResult( QObject::tr( "Duplicated names" ), QObject::tr( "Layers/groups have the same name or short name." ), duplicateNames.join( QStringLiteral( ", " ) ) ); } if ( !regExpMessages.empty() ) { - html += QStringLiteral( "

    " ) + QObject::tr( "Some layer short names have to be updated:" ) + QStringLiteral( "

    • " ); - html += regExpMessages.join( QStringLiteral( "
    • " ) ); - html += QStringLiteral( "
    " ); - } - else - { - html += QStringLiteral( "

    " ) + QObject::tr( "All layer short names are well formed" ) + QStringLiteral( "

    " ); + result = false; + results << ValidationResult( QObject::tr( "Short names" ), QObject::tr( "Layers short names have to be updated." ), regExpMessages.join( QStringLiteral( ", " ) ) ); } if ( !encodingMessages.empty() ) { - html += QStringLiteral( "

    " ) + QObject::tr( "Some layer encodings are not set:" ) + QStringLiteral( "

    • " ); - html += encodingMessages.join( QStringLiteral( "
    • " ) ); - html += QStringLiteral( "
    " ); - } - else - { - html += QStringLiteral( "

    " ) + QObject::tr( "All layer encodings are set" ) + QStringLiteral( "

    " ); + result = false; + results << ValidationResult( QObject::tr( "Encoding" ), QObject::tr( "Encoding is not set." ), encodingMessages.join( QStringLiteral( ", " ) ) ); } - return html; + return result; } diff --git a/src/core/qgsprojectservervalidator.h b/src/core/qgsprojectservervalidator.h index 8ed51f877ee8..67b0478c681b 100644 --- a/src/core/qgsprojectservervalidator.h +++ b/src/core/qgsprojectservervalidator.h @@ -1,9 +1,28 @@ +/*************************************************************************** + qgsprojectservervalidator.h + --------------------------- + begin : March 2020 + copyright : (C) 2020 by Etienne Trimaille + email : etienne dot trimaille at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSPROJECTSERVERVALIDATOR_H +#define QGSPROJECTSERVERVALIDATOR_H + #include "qgis_core.h" +#include "qgslayermetadatavalidator.h" #include "qgslayertreegroup.h" #include "qgslayertree.h" -#ifndef QGSPROJECTSERVERVALIDATOR_H -#define QGSPROJECTSERVERVALIDATOR_H /** * \ingroup core @@ -11,23 +30,29 @@ * \brief Project server validator. * \since QGIS 3.14 */ -class CORE_EXPORT QgsProjectServerValidator +class CORE_EXPORT QgsProjectServerValidator : public QgsAbstractBaseValidator { public: /** - * Recursive function to check a layer tree group. - * The function will collect OWS names and encoding for each layers. - * \since QGIS 3.14 + * Constructor for QgsProjectServerValidator. */ - static void checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ); + QgsProjectServerValidator() = default; /** - * Check a layer tree. + * Validates a layer tree to avoid some problems on QGIS Server, and returns TRUE if it's considered valid. + * If validation fails, the \a 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 + * \param results results of the validation + * \returns bool * \since QGIS 3.14 */ - static QString projectStatusHtml( QgsLayerTree *layerTree ); + bool validate( QgsLayerTree *layerTree, QList< QgsAbstractBaseValidator::ValidationResult > &results SIP_OUT ) const; + + private: + static void browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages ); }; diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index 32a056c8f48c..8cf5020c3a43 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -186,6 +186,7 @@ ADD_PYTHON_TEST(PyQgsProcessingAlgDecorator test_processing_alg_decorator.py) ADD_PYTHON_TEST(PyQgsImportIntoPostGIS test_processing_importintopostgis.py) ADD_PYTHON_TEST(PyQgsProjectionSelectionWidgets test_qgsprojectionselectionwidgets.py) ADD_PYTHON_TEST(PyQgsProjectMetadata test_qgsprojectmetadata.py) +ADD_PYTHON_TEST(PyQgsProjectServerValidator test_qgsprojectservervalidator.py) ADD_PYTHON_TEST(PyQgsPropertyOverrideButton test_qgspropertyoverridebutton.py) ADD_PYTHON_TEST(PyQgsProviderConnectionComboBox test_qgsproviderconnectioncombobox.py) ADD_PYTHON_TEST(PyQgsProviderConnectionModel test_qgsproviderconnectionmodel.py) diff --git a/tests/src/python/test_qgsprojectservervalidator.py b/tests/src/python/test_qgsprojectservervalidator.py new file mode 100644 index 000000000000..dabbe4dd3f15 --- /dev/null +++ b/tests/src/python/test_qgsprojectservervalidator.py @@ -0,0 +1,47 @@ +"""QGIS Unit tests for QgsProjectServerValidator + +From build dir, run: +ctest -R PyQgsProjectServerValidator -V + +.. note:: This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +""" +__author__ = 'Etienne Trimaille' +__date__ = '27/03/2020' +__copyright__ = 'Copyright 2020, The QGIS Project' + +from qgis.core import ( + QgsProject, + QgsVectorLayer, + QgsProjectServerValidator, +) +from qgis.testing import start_app, unittest + +app = start_app() + + +class TestQgsprojectServerValidator(unittest.TestCase): + + def test_project_server_validator(self): + """Test project server validator.""" + validator = QgsProjectServerValidator() + project = QgsProject() + 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") + project.addMapLayers([layer_1]) + + valid, results = validator.validate(project.layerTreeRoot()) + self.assertFalse(valid) + self.assertEqual(results[0].section, 'Duplicated names') + + +if __name__ == '__main__': + unittest.main() From 4334a995881d156f3eb387baebcc08d6bf8abddf Mon Sep 17 00:00:00 2001 From: Etienne Trimaille Date: Mon, 30 Mar 2020 15:57:55 +0200 Subject: [PATCH 3/3] 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__':