diff --git a/src/gui/ogr/qgsgdalguiutils.cpp b/src/gui/ogr/qgsgdalguiutils.cpp index d5a097cbc7e..5a5ef2ffab9 100644 --- a/src/gui/ogr/qgsgdalguiutils.cpp +++ b/src/gui/ogr/qgsgdalguiutils.cpp @@ -222,16 +222,20 @@ QString QgsGdalGuiUtils::createDatabaseURI( const QString &connectionType, const QString QgsGdalGuiUtils::createProtocolURI( const QString &type, const QString &url, const QString &configId, const QString &username, const QString &password, bool expandAuthConfig ) { - QString uri; + QString uri = url; + QString prefix; if ( type == QLatin1String( "vsicurl" ) ) { - uri = url; - // If no protocol is provided in the URL, default to HTTP - if ( !uri.startsWith( "http://" ) && !uri.startsWith( "https://" ) && !uri.startsWith( "ftp://" ) ) + prefix = QStringLiteral( "/vsicurl/" ); + if ( !uri.startsWith( prefix ) ) { - uri.prepend( QStringLiteral( "http://" ) ); + // If no protocol is provided in the URL, default to HTTP + if ( !uri.startsWith( QLatin1String( "http://" ) ) && !uri.startsWith( QLatin1String( "https://" ) ) && !uri.startsWith( QLatin1String( "ftp://" ) ) ) + { + uri.prepend( QStringLiteral( "http://" ) ); + } + uri.prepend( prefix ); } - uri.prepend( QStringLiteral( "/vsicurl/" ) ); } else if ( type == QLatin1String( "vsis3" ) || type == QLatin1String( "vsigs" ) @@ -241,25 +245,40 @@ QString QgsGdalGuiUtils::createProtocolURI( const QString &type, const QString & || type == QLatin1String( "vsiswift" ) || type == QLatin1String( "vsihdfs" ) ) { - uri = url; - uri.prepend( QStringLiteral( "/%1/" ).arg( type ) ); + prefix = QStringLiteral( "/%1/" ).arg( type ); + if ( !uri.startsWith( prefix ) ) + { + uri.prepend( prefix ); + } } // catching both GeoJSON and GeoJSONSeq else if ( type.startsWith( QLatin1String( "GeoJSON" ) ) ) { - uri = url; + // no change needed for now } else if ( type == QLatin1String( "CouchDB" ) ) { - uri = QStringLiteral( "couchdb:%1" ).arg( url ); + prefix = QStringLiteral( "couchdb:" ); + if ( !uri.startsWith( prefix ) ) + { + uri.prepend( prefix ); + } } else if ( type == QLatin1String( "DODS/OPeNDAP" ) ) { - uri = QStringLiteral( "DODS:%1" ).arg( url ); + prefix = QStringLiteral( "DODS:" ); + if ( !uri.startsWith( prefix ) ) + { + uri.prepend( prefix ); + } } else if ( type == QLatin1String( "WFS3" ) ) { - uri = QStringLiteral( "WFS3:%1" ).arg( url ); + prefix = QStringLiteral( "WFS3:" ); + if ( !uri.startsWith( prefix ) ) + { + uri.prepend( prefix ); + } } QgsDebugMsgLevel( "Connection type is=" + type + " and uri=" + uri, 2 ); // Update URI with authentication information diff --git a/tests/src/gui/CMakeLists.txt b/tests/src/gui/CMakeLists.txt index d995d0213d6..8fb6cdf80bf 100644 --- a/tests/src/gui/CMakeLists.txt +++ b/tests/src/gui/CMakeLists.txt @@ -47,6 +47,7 @@ set(TESTS testqgsmessagebar.cpp testprojectionissues.cpp testqgsgui.cpp + testqgsgdalguiutils.cpp testprocessinggui.cpp testqgsprocessingmodel.cpp testqgsrubberband.cpp diff --git a/tests/src/gui/testqgsgdalguiutils.cpp b/tests/src/gui/testqgsgdalguiutils.cpp new file mode 100644 index 00000000000..8e19aee29b1 --- /dev/null +++ b/tests/src/gui/testqgsgdalguiutils.cpp @@ -0,0 +1,231 @@ +/*************************************************************************** + testqgsgdalguiutils.cpp + -------------------------------------- + Date : 12.11.2024 + Copyright : (C) 2024 Abdullaev Ruslan + Email : caboose7 at yandex 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 "qgstest.h" +#include "qgsgdalguiutils.h" +#include "qgsapplication.h" + +class TestQgsGdalGuiUtils : public QObject +{ + Q_OBJECT + + public: + TestQgsGdalGuiUtils(); + + private slots: + void initTestCase(); + void cleanupTestCase(); + + void checkUriBuilding(); +}; + +TestQgsGdalGuiUtils::TestQgsGdalGuiUtils() + : QObject() +{ +} + +void TestQgsGdalGuiUtils::initTestCase() +{ + QgsApplication::init(); + QgsApplication::initQgis(); +} + +void TestQgsGdalGuiUtils::checkUriBuilding() +{ + // Test vsicurl: no protocol -> should default to http + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "www.test.com" ), QString(), QString(), QString(), false ); + QString expected( "/vsicurl/http://www.test.com" ); + QCOMPARE( actual, expected ); + } + + // Test vsicurl: with http already specified + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "http://www.test.com" ), QString(), QString(), QString(), false ); + // Already has protocol, just add prefix + QString expected( "/vsicurl/http://www.test.com" ); + QCOMPARE( actual, expected ); + } + + // Test vsicurl: with https + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "https://data.test.com/path" ), QString(), QString(), QString(), false ); + QString expected( "/vsicurl/https://data.test.com/path" ); + QCOMPARE( actual, expected ); + } + + // Test vsicurl: with ftp + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "ftp://files.test.com" ), QString(), QString(), QString(), false ); + QString expected( "/vsicurl/ftp://files.test.com" ); + QCOMPARE( actual, expected ); + } + + // Test vsicurl: prefix already included + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "/vsicurl/http://already.prefixed.com" ), QString(), QString(), QString(), false ); + // No change expected + QString expected( "/vsicurl/http://already.prefixed.com" ); + QCOMPARE( actual, expected ); + } + + // Test vsis3: no prefix yet + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsis3" ), QLatin1String( "bucket/key" ), QString(), QString(), QString(), false ); + QString expected( "/vsis3/bucket/key" ); + QCOMPARE( actual, expected ); + } + + // Test vsis3: prefix already included + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsis3" ), QLatin1String( "/vsis3/mydata" ), QString(), QString(), QString(), false ); + QString expected( "/vsis3/mydata" ); + QCOMPARE( actual, expected ); + } + + // Test vsigs + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsigs" ), QLatin1String( "gs://mybucket/data" ), QString(), QString(), QString(), false ); + // Even if gs:// is specified, code only prepends /vsigs/ if not present + QString expected( "/vsigs/gs://mybucket/data" ); + QCOMPARE( actual, expected ); + } + + // Test vsiaz + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsiaz" ), QLatin1String( "mycontainer/myfile" ), QString(), QString(), QString(), false ); + QString expected( "/vsiaz/mycontainer/myfile" ); + QCOMPARE( actual, expected ); + } + + // Test vsiadls + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsiadls" ), QLatin1String( "adls_path" ), QString(), QString(), QString(), false ); + QString expected( "/vsiadls/adls_path" ); + QCOMPARE( actual, expected ); + } + + // Test vsioss + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsioss" ), QLatin1String( "my_oss_bucket/file" ), QString(), QString(), QString(), false ); + QString expected( "/vsioss/my_oss_bucket/file" ); + QCOMPARE( actual, expected ); + } + + // Test vsiswift + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsiswift" ), QLatin1String( "swift_container/object" ), QString(), QString(), QString(), false ); + QString expected( "/vsiswift/swift_container/object" ); + QCOMPARE( actual, expected ); + } + + // Test vsihdfs + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsihdfs" ), QLatin1String( "hdfs_path" ), QString(), QString(), QString(), false ); + QString expected( "/vsihdfs/hdfs_path" ); + QCOMPARE( actual, expected ); + } + + // Test GeoJSON + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "GeoJSON" ), QLatin1String( "file.json" ), QString(), QString(), QString(), false ); + // No prefix changes for GeoJSON + QString expected( "file.json" ); + QCOMPARE( actual, expected ); + } + + // Test GeoJSONSeq + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "GeoJSONSeq" ), QLatin1String( "seq_file.json" ), QString(), QString(), QString(), false ); + // No prefix changes for GeoJSONSeq + QString expected( "seq_file.json" ); + QCOMPARE( actual, expected ); + } + + // Test CouchDB: no prefix yet + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "CouchDB" ), QLatin1String( "localhost:5984/db" ), QString(), QString(), QString(), false ); + QString expected( "couchdb:localhost:5984/db" ); + QCOMPARE( actual, expected ); + } + + // Test CouchDB: prefix already included + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "CouchDB" ), QLatin1String( "couchdb:localhost:5984/db" ), QString(), QString(), QString(), false ); + QString expected( "couchdb:localhost:5984/db" ); + QCOMPARE( actual, expected ); + } + + // Test DODS/OPeNDAP: no prefix + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "DODS/OPeNDAP" ), QLatin1String( "http://opendap.data" ), QString(), QString(), QString(), false ); + QString expected( "DODS:http://opendap.data" ); + QCOMPARE( actual, expected ); + } + + // Test DODS/OPeNDAP: prefix already included + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "DODS/OPeNDAP" ), QLatin1String( "DODS:http://opendap.data" ), QString(), QString(), QString(), false ); + QString expected( "DODS:http://opendap.data" ); + QCOMPARE( actual, expected ); + } + + // Test WFS3: no prefix + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "WFS3" ), QLatin1String( "https://mywfs3.org" ), QString(), QString(), QString(), false ); + QString expected( "WFS3:https://mywfs3.org" ); + QCOMPARE( actual, expected ); + } + + // Test WFS3: prefix already + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "WFS3" ), QLatin1String( "WFS3:https://mywfs3.org" ), QString(), QString(), QString(), false ); + QString expected( "WFS3:https://mywfs3.org" ); + QCOMPARE( actual, expected ); + } + + // Test with configId and expandAuthConfig = false + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "mydata.com" ), QLatin1String( "myconfig" ), QString(), QString(), false ); + // Should prepend prefix and protocol + QString expected( "/vsicurl/http://mydata.com authcfg='myconfig'" ); + QCOMPARE( actual, expected ); + } + + // Test with configId and no username/password, expandAuthConfig = true + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "CouchDB" ), QLatin1String( "mydb" ), QLatin1String( "ab34567" ), QString(), QString(), true ); + // Prefix is added, then authcfg updated. If no real auth expansion, it remains as is. + // Actual code tries to expand, if fails, it returns with authcfg. + QString expected( "couchdb:mydb" ); + QCOMPARE( actual, expected ); + } + + // Test with username/password and no configId + { + QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "https://securedata.com" ), QString(), QLatin1String( "user" ), QLatin1String( "pass" ), false ); + // Insert credentials into the URI after "://" + QString expected( "/vsicurl/https://user:pass@securedata.com" ); + QCOMPARE( actual, expected ); + } +} + +void TestQgsGdalGuiUtils::cleanupTestCase() +{ + QgsApplication::exitQgis(); +} + +QGSTEST_MAIN( TestQgsGdalGuiUtils ) +#include "testqgsgdalguiutils.moc"