1 /***************************************************************************
2     testqgsfilefiledownloader.cpp
3      --------------------------------------
4     Date                 : 09.03.2020
5     Copyright            : (C) 2020 Alessandro Pasotti
6     Email                : elpaso at itopen dot it
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 
17 #include "qgstest.h"
18 #include <QObject>
19 #include <QDialog>
20 #include <QSignalSpy>
21 #include <QTemporaryDir>
22 
23 #include "qgsnewdatabasetablenamewidget.h"
24 #include "qgsprovidermetadata.h"
25 #include "qgsproviderregistry.h"
26 #include "qgsabstractproviderconnection.h"
27 #include "qgsdataitem.h"
28 
29 class TestQgsNewDatabaseTableNameWidget: public QObject
30 {
31     Q_OBJECT
32   public:
33     TestQgsNewDatabaseTableNameWidget() = default;
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.
38     void init(); // will be called before each testfunction is executed.
39     void cleanup(); // will be called after every testfunction.
40 
41     void testWidgetFilters();
42     void testWidgetSignalsPostgres();
43     void testWidgetSignalsGeopackage();
44 
45   private:
46 
47     std::unique_ptr<QgsAbstractProviderConnection> mPgConn;
48     std::unique_ptr<QgsAbstractProviderConnection> mGpkgConn;
49     QTemporaryDir mDir;
50     QString mGpkgPath;
51 };
52 
initTestCase()53 void TestQgsNewDatabaseTableNameWidget::initTestCase()
54 {
55 
56   QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
57   QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
58   QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST-NEW-DBTABLE-WIDGET" ) );
59 
60   QgsApplication::init();
61   QgsApplication::initQgis();
62 
63   // Add some connections to test with
64   QgsProviderMetadata *md = nullptr;
65 #ifdef ENABLE_PGTEST
66   md = QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "postgres" ) );
67   mPgConn.reset( md->createConnection( qgetenv( "QGIS_PGTEST_DB" ), { } ) );
68   md->saveConnection( mPgConn.get(), QStringLiteral( "PG_1" ) );
69   md->saveConnection( mPgConn.get(), QStringLiteral( "PG_2" ) );
70 #endif
71 
72   md = QgsProviderRegistry::instance()->providerMetadata( QStringLiteral( "ogr" ) );
73   QString errCause;
74   QMap<int, int> m;
75   mGpkgPath = mDir.filePath( QStringLiteral( "test.gpkg" ) );
76   const QMap<QString, QVariant> options { { QStringLiteral( "layerName" ), QString( "test_layer" ) } };
77   QVERIFY( md->createEmptyLayer( mGpkgPath,
78                                  QgsFields(),
79                                  QgsWkbTypes::Type::Point,
80                                  QgsCoordinateReferenceSystem::fromEpsgId( 4326 ),
81                                  true,
82                                  m,
83                                  errCause,
84                                  &options ) == Qgis::VectorExportResult::Success );
85   QVERIFY( errCause.isEmpty() );
86   mGpkgConn.reset( md->createConnection( mDir.filePath( QStringLiteral( "test.gpkg" ) ), { } ) );
87   md->saveConnection( mGpkgConn.get(), QStringLiteral( "GPKG_1" ) );
88 
89 }
90 
cleanupTestCase()91 void TestQgsNewDatabaseTableNameWidget::cleanupTestCase()
92 {
93   QgsApplication::exitQgis();
94 }
95 
init()96 void TestQgsNewDatabaseTableNameWidget::init()
97 {
98 }
99 
cleanup()100 void TestQgsNewDatabaseTableNameWidget::cleanup()
101 {
102 }
103 
testWidgetFilters()104 void TestQgsNewDatabaseTableNameWidget::testWidgetFilters()
105 {
106   std::unique_ptr<QgsNewDatabaseTableNameWidget> w { std::make_unique<QgsNewDatabaseTableNameWidget>( nullptr, QStringList{ "NOT_EXISTS" } ) };
107   QCOMPARE( w->mBrowserProxyModel.rowCount(), 0 );
108   std::unique_ptr<QgsNewDatabaseTableNameWidget> w2 { std::make_unique<QgsNewDatabaseTableNameWidget>( nullptr ) };
109   QVERIFY( w2->mBrowserProxyModel.rowCount() > 0 );
110   std::unique_ptr<QgsNewDatabaseTableNameWidget> w3 { std::make_unique<QgsNewDatabaseTableNameWidget>( nullptr, QStringList{ "postgres" } ) };
111   QVERIFY( w3->mBrowserProxyModel.rowCount() > 0 );
112 }
113 
114 
testWidgetSignalsPostgres()115 void TestQgsNewDatabaseTableNameWidget::testWidgetSignalsPostgres()
116 {
117 #ifdef ENABLE_PGTEST
118   std::unique_ptr<QgsNewDatabaseTableNameWidget> w { std::make_unique<QgsNewDatabaseTableNameWidget>( nullptr, QStringList{ "postgres" } ) };
119 
120   auto index = w->mBrowserModel->findPath( QStringLiteral( "pg:/PG_1" ) );
121   QVERIFY( index.isValid() );
122   w->mBrowserModel->dataItem( index )->populate( true );
123   w->mBrowserTreeView->expandAll();
124 
125   QVERIFY( ! w->isValid() );
126 
127   QSignalSpy validationSpy( w.get(), SIGNAL( validationChanged( bool ) ) );
128   QSignalSpy schemaSpy( w.get(), SIGNAL( schemaNameChanged( QString ) ) );
129   QSignalSpy tableSpy( w.get(), SIGNAL( tableNameChanged( QString ) ) );
130   QSignalSpy providerSpy( w.get(), SIGNAL( providerKeyChanged( QString ) ) );
131   QSignalSpy uriSpy( w.get(), SIGNAL( uriChanged( QString ) ) );
132 
133   index = w->mBrowserProxyModel.mapToSource( w->mBrowserProxyModel.index( 0, 0 ) );
134   QVERIFY( index.isValid() );
135   QCOMPARE( w->mBrowserModel->data( index, Qt::DisplayRole ).toString(), QString( "PostGIS" ) );
136   QRect rect = w->mBrowserTreeView->visualRect( w->mBrowserProxyModel.mapFromSource( index ) );
137   QVERIFY( rect.isValid() );
138   QTest::mouseClick( w->mBrowserTreeView->viewport(), Qt::LeftButton, Qt::KeyboardModifiers(), rect.topLeft() );
139 
140   QVERIFY( ! w->isValid() );
141 
142   /*
143   QDialog d;
144   QVBoxLayout l;
145   l.addWidget( w.get() );
146   d.setLayout( &l );
147   d.exec();
148   //*/
149 
150   QCOMPARE( providerSpy.count(), 1 );
151   QCOMPARE( uriSpy.count(), 0 );
152   QCOMPARE( tableSpy.count(), 0 );
153   QCOMPARE( schemaSpy.count(), 0 );
154   QCOMPARE( validationSpy.count(), 0 );
155   auto arguments = providerSpy.takeLast();
156   QCOMPARE( arguments.at( 0 ).toString(), QString( "postgres" ) );
157 
158   // Find qgis_test schema item
159   index = w->mBrowserModel->findPath( QStringLiteral( "pg:/PG_1/qgis_test" ) );
160   QVERIFY( index.isValid() );
161   w->mBrowserTreeView->scrollTo( w->mBrowserProxyModel.mapFromSource( index ) );
162   rect = w->mBrowserTreeView->visualRect( w->mBrowserProxyModel.mapFromSource( index ) );
163   QVERIFY( rect.isValid() );
164   QTest::mouseClick( w->mBrowserTreeView->viewport(), Qt::LeftButton, Qt::KeyboardModifiers(), rect.center() );
165 
166   QVERIFY( ! w->isValid() );
167 
168   QCOMPARE( validationSpy.count(), 0 );
169   QCOMPARE( schemaSpy.count(), 1 );
170   QCOMPARE( uriSpy.count(), 1 );
171   arguments = schemaSpy.takeLast();
172   QCOMPARE( arguments.at( 0 ).toString(), QString( "qgis_test" ) );
173   arguments = uriSpy.takeLast();
174   QVERIFY( ! arguments.at( 0 ).toString().isEmpty() );
175 
176   w->mNewTableName->setText( QStringLiteral( "someNewTableData" ) ); //#spellok
177   QCOMPARE( tableSpy.count(), 1 );
178   arguments = tableSpy.takeLast();
179   QCOMPARE( arguments.at( 0 ).toString(), QString( "someNewTableData" ) ); //#spellok
180   QCOMPARE( validationSpy.count(), 1 );
181   arguments = validationSpy.takeLast();
182   QCOMPARE( arguments.at( 0 ).toBool(), true );
183   QVERIFY( w->isValid() );
184 
185   // Test getters
186   QCOMPARE( w->table(), QString( "someNewTableData" ) ); //#spellok
187   QCOMPARE( w->schema(), QString( "qgis_test" ) );
188   QCOMPARE( w->dataProviderKey(), QString( "postgres" ) );
189   QVERIFY( w->uri().contains( R"("qgis_test"."someNewTableData")" ) ); //#spellok
190 
191   // Test unique and make it invalid again so we get a status change
192   w->mNewTableName->setText( QStringLiteral( "someData" ) );
193   QVERIFY( ! w->isValid() );
194   QCOMPARE( tableSpy.count(), 1 );
195   arguments = tableSpy.takeLast();
196   QCOMPARE( arguments.at( 0 ).toString(), QString( "someData" ) );
197   QCOMPARE( validationSpy.count(), 1 );
198   arguments = validationSpy.takeLast();
199   QCOMPARE( arguments.at( 0 ).toBool(), false );
200 
201   // Now select another schema
202   index = w->mBrowserModel->findPath( QStringLiteral( "pg:/PG_1/public" ) );
203   QVERIFY( index.isValid() );
204   w->mBrowserTreeView->scrollTo( w->mBrowserProxyModel.mapFromSource( index ) );
205   rect = w->mBrowserTreeView->visualRect( w->mBrowserProxyModel.mapFromSource( index ) );
206   QVERIFY( rect.isValid() );
207   QTest::mouseClick( w->mBrowserTreeView->viewport(), Qt::LeftButton, Qt::KeyboardModifiers(), rect.center() );
208   QCOMPARE( w->schema(), QString( "public" ) );
209   QVERIFY( w->isValid() );
210   QCOMPARE( validationSpy.count(), 1 );
211   arguments = validationSpy.takeLast();
212   QCOMPARE( arguments.at( 0 ).toBool(), true );
213   QCOMPARE( schemaSpy.count(), 1 );
214   arguments = schemaSpy.takeLast();
215   QCOMPARE( arguments.at( 0 ).toString(), QString( "public" ) );
216 
217   // Test getters
218   QCOMPARE( w->table(), QString( "someData" ) );
219   QCOMPARE( w->schema(), QString( "public" ) );
220   QCOMPARE( w->dataProviderKey(), QString( "postgres" ) );
221   QVERIFY( w->uri().contains( R"("public"."someData")" ) );
222 #endif
223 }
224 
testWidgetSignalsGeopackage()225 void TestQgsNewDatabaseTableNameWidget::testWidgetSignalsGeopackage()
226 {
227 #ifdef ENABLE_PGTEST
228   std::unique_ptr<QgsNewDatabaseTableNameWidget> w { std::make_unique<QgsNewDatabaseTableNameWidget>( nullptr, QStringList{ "ogr" } ) };
229 
230   auto index = w->mBrowserModel->findPath( QStringLiteral( "pg:/PG_1" ) );
231   QVERIFY( index.isValid() );
232   w->mBrowserModel->dataItem( index )->populate( true );
233   w->mBrowserTreeView->expandAll();
234 
235   QVERIFY( ! w->isValid() );
236 
237   QSignalSpy validationSpy( w.get(), SIGNAL( validationChanged( bool ) ) );
238   QSignalSpy schemaSpy( w.get(), SIGNAL( schemaNameChanged( QString ) ) );
239   const QSignalSpy tableSpy( w.get(), SIGNAL( tableNameChanged( QString ) ) );
240   const QSignalSpy providerSpy( w.get(), SIGNAL( providerKeyChanged( QString ) ) );
241   QSignalSpy uriSpy( w.get(), SIGNAL( uriChanged( QString ) ) );
242 
243   /*
244   QDialog d;
245   QVBoxLayout l;
246   l.addWidget( w.get() );
247   d.setLayout( &l );
248   d.exec();
249   //*/
250 
251   uriSpy.clear();
252   index = w->mBrowserModel->findPath( QStringLiteral( "gpkg:/%1" ).arg( mGpkgPath ) );
253   QVERIFY( index.isValid() );
254   w->mBrowserTreeView->scrollTo( w->mBrowserProxyModel.mapFromSource( index ) );
255   const auto rect = w->mBrowserTreeView->visualRect( w->mBrowserProxyModel.mapFromSource( index ) );
256   QVERIFY( rect.isValid() );
257   QTest::mouseClick( w->mBrowserTreeView->viewport(), Qt::LeftButton, Qt::KeyboardModifiers(), rect.center() );
258 
259   QVERIFY( ! w->isValid() );
260   QCOMPARE( schemaSpy.count(), 1 );
261   auto arguments = schemaSpy.takeLast();
262   QCOMPARE( arguments.at( 0 ).toString(), mGpkgPath );
263   QCOMPARE( uriSpy.count(), 1 );
264   arguments = uriSpy.takeLast();
265   QCOMPARE( arguments.at( 0 ).toString(), mGpkgPath );
266 
267   w->mNewTableName->setText( QStringLiteral( "newTableName" ) );
268   QVERIFY( w->isValid() );
269   QCOMPARE( validationSpy.count(), 1 );
270   arguments = validationSpy.takeLast();
271   QCOMPARE( arguments.at( 0 ).toBool(), true );
272 
273   // Test getters
274   QCOMPARE( w->table(), QString( "newTableName" ) );
275   QCOMPARE( w->schema(), mGpkgPath );
276   QCOMPARE( w->dataProviderKey(), QString( "ogr" ) );
277   QCOMPARE( w->uri(), QString( mGpkgPath + QStringLiteral( "|layername=newTableName" ) ) );
278 #endif
279 }
280 
281 QGSTEST_MAIN( TestQgsNewDatabaseTableNameWidget )
282 #include "testqgsnewdatabasetablewidget.moc"
283 
284 
285