1 /***************************************************************************
2 testqgsogrprovidergui.cpp - TestQgsOgrProviderGui
3
4 ---------------------
5 begin : 10.11.2017
6 copyright : (C) 2017 by Alessandro Pasotti
7 email : apasotti at boundlessgeo dot com
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17 #include "qgstest.h"
18 #include <QSignalSpy>
19 #include <QTemporaryFile>
20
21 #include "qgsdataitemguiprovider.h"
22 #include "qgsdataitemguiproviderregistry.h"
23 #include "qgsgeopackagedataitems.h"
24 #include "qgsgui.h"
25 #include "qgsvectorlayer.h"
26
27 /**
28 * \ingroup UnitTests
29 * This is a unit test for the ogr provider GUI
30 */
31 class TestQgsOgrProviderGui : public QObject
32 {
33 Q_OBJECT
34
35 private slots:
36 void initTestCase();// will be called before the first testfunction is executed.
37 void cleanupTestCase();// will be called after the last testfunction was executed.
init()38 void init() {}// will be called before each testfunction is executed.
cleanup()39 void cleanup() {}// will be called after every testfunction.
40
41 void providersRegistered();
42 //! Test GPKG data items rename
43 void testGpkgDataItemRename();
44
45 private:
46 QString mTestDataDir;
47 };
48
49
50 //runs before all tests
initTestCase()51 void TestQgsOgrProviderGui::initTestCase()
52 {
53 // init QGIS's paths - true means that all path will be inited from prefix
54 QgsApplication::init();
55 QgsApplication::initQgis();
56
57 mTestDataDir = QStringLiteral( TEST_DATA_DIR ) + '/'; //defined in CmakeLists.txt
58 }
59
providersRegistered()60 void TestQgsOgrProviderGui::providersRegistered()
61 {
62 const QList<QgsDataItemGuiProvider *> providers = QgsGui::dataItemGuiProviderRegistry()->providers();
63 bool hasOgrProvider = false;
64 bool hasGpkgProvider = false;
65 for ( QgsDataItemGuiProvider *provider : providers )
66 {
67 if ( provider->name() == QLatin1String( "ogr_items" ) )
68 hasOgrProvider = true;
69 if ( provider->name() == QLatin1String( "geopackage_items" ) )
70 hasGpkgProvider = true;
71 }
72 QVERIFY( hasOgrProvider );
73 QVERIFY( hasGpkgProvider );
74 }
75
76 //runs after all tests
cleanupTestCase()77 void TestQgsOgrProviderGui::cleanupTestCase()
78 {
79 QgsApplication::exitQgis();
80 }
81
testGpkgDataItemRename()82 void TestQgsOgrProviderGui::testGpkgDataItemRename()
83 {
84 QTemporaryFile f( QStringLiteral( "qgis-XXXXXX.gpkg" ) );
85 f.open();
86 f.close();
87 const QString fileName { f.fileName( ) };
88 f.remove();
89 QVERIFY( QFile::copy( QStringLiteral( "%1/provider/bug_21227-rename-styles.gpkg" ).arg( mTestDataDir ), fileName ) );
90
91 // create geopackage item and populate it with layers
92 QgsGeoPackageCollectionItem gpkgItem( nullptr, QStringLiteral( "test gpkg" ), QStringLiteral( "gpkg:/%1" ).arg( fileName ) );
93 gpkgItem.populate( true );
94 const QVector<QgsDataItem *> items = gpkgItem.children();
95 QgsDataItem *itemLayer1 = nullptr;
96 for ( QgsDataItem *item : items )
97 {
98 if ( item->name() == QLatin1String( "layer 1" ) )
99 itemLayer1 = item;
100 }
101 QVERIFY( itemLayer1 );
102
103 QSignalSpy spyDataChanged( &gpkgItem, &QgsDataItem::dataChanged );
104
105 // try to rename
106 const QList<QgsDataItemGuiProvider *> providers = QgsGui::dataItemGuiProviderRegistry()->providers();
107 bool success = false;
108 for ( QgsDataItemGuiProvider *provider : providers )
109 {
110 if ( provider->rename( itemLayer1, QStringLiteral( "layer 3" ), QgsDataItemGuiContext() ) )
111 {
112 success = true;
113 // also check it was the correct provider
114 QCOMPARE( provider->name(), QStringLiteral( "geopackage_items" ) );
115 }
116 }
117 QVERIFY( success );
118
119 // gpkg item gets refreshed in the background and there will be multiple dataChanged signals
120 // emitted unfortunately, so let's just wait until no more data changes signals are coming.
121 // Animation of "loading" icon also triggers dataChanged() signals, making even the number
122 // of signals unpredictable...
123 while ( spyDataChanged.wait( 500 ) )
124 ;
125
126 // Check that the style is still available
127 const QgsVectorLayer metadataLayer( QStringLiteral( "/%1|layername=layer_styles" ).arg( fileName ) );
128 QVERIFY( metadataLayer.isValid() );
129 QgsFeature feature;
130 QgsFeatureIterator it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 3'" ) ) ) );
131 QVERIFY( it.nextFeature( feature ) );
132 QVERIFY( feature.isValid() );
133 QCOMPARE( feature.attribute( QStringLiteral( "styleName" ) ).toString(), QString( "style for layer 1" ) );
134 it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 1' " ) ) ) );
135 QVERIFY( !it.nextFeature( feature ) );
136 it = metadataLayer.getFeatures( QgsFeatureRequest( QgsExpression( QStringLiteral( "\"f_table_name\" = 'layer 2' " ) ) ) );
137 QVERIFY( it.nextFeature( feature ) );
138 QVERIFY( feature.isValid() );
139 QCOMPARE( feature.attribute( QStringLiteral( "styleName" ) ).toString(), QString( "style for layer 2" ) );
140 }
141
142
143 QGSTEST_MAIN( TestQgsOgrProviderGui )
144 #include "testqgsogrprovidergui.moc"
145