File indexing completed on 2024-11-10 04:40:22
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Daniel Vrátil <dvratil@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 * 0006 */ 0007 0008 #include "qtest_akonadi.h" 0009 0010 #include "shared/akscopeguard.h" 0011 #include "shared/aktest.h" 0012 0013 #include "subscriptiondialog.h" 0014 #include "subscriptionjob_p.h" 0015 #include "subscriptionmodel_p.h" 0016 0017 #include <QCheckBox> 0018 #include <QDialog> 0019 #include <QDialogButtonBox> 0020 #include <QLineEdit> 0021 #include <QPushButton> 0022 #include <QSignalSpy> 0023 #include <QTest> 0024 #include <QTreeView> 0025 0026 #include <deque> 0027 #include <memory> 0028 0029 using namespace Akonadi; 0030 0031 class SubscriptionDialogTest : public QObject 0032 { 0033 Q_OBJECT 0034 0035 struct TestSetup { 0036 enum { 0037 defaultCollectionCount = 7, 0038 }; 0039 0040 TestSetup() 0041 : widget(std::make_unique<SubscriptionDialog>(QStringList{Collection::mimeType(), QStringLiteral("application/octet-stream")})) 0042 { 0043 widget->setAttribute(Qt::WA_DeleteOnClose, false); 0044 widget->show(); 0045 0046 model = widget->findChild<SubscriptionModel *>(); 0047 QVERIFY(model); 0048 QSignalSpy modelLoadedSpy(model, &SubscriptionModel::modelLoaded); 0049 0050 buttonBox = widget->findChild<QDialogButtonBox *>(); 0051 QVERIFY(buttonBox); 0052 QVERIFY(!buttonBox->button(QDialogButtonBox::Ok)->isEnabled()); 0053 searchLineEdit = widget->findChild<QLineEdit *>(QStringLiteral("searchLineEdit")); 0054 QVERIFY(searchLineEdit); 0055 subscribedOnlyChkBox = widget->findChild<QCheckBox *>(QStringLiteral("subscribedOnlyCheckBox")); 0056 QVERIFY(subscribedOnlyChkBox); 0057 collectionView = widget->findChild<QTreeView *>(QStringLiteral("collectionView")); 0058 QVERIFY(collectionView); 0059 subscribeButton = widget->findChild<QPushButton *>(QStringLiteral("subscribeButton")); 0060 QVERIFY(subscribeButton); 0061 unsubscribeButton = widget->findChild<QPushButton *>(QStringLiteral("unsubscribeButton")); 0062 QVERIFY(unsubscribeButton); 0063 0064 QVERIFY(QTest::qWaitForWindowActive(widget.get())); 0065 QVERIFY(modelLoadedSpy.wait()); 0066 QTest::qWait(100); 0067 0068 // Helps with testing :) 0069 collectionView->expandAll(); 0070 0071 // Post-setup conditions 0072 QCOMPARE(countTotalRows(), defaultCollectionCount); 0073 QVERIFY(buttonBox->button(QDialogButtonBox::Ok)->isEnabled()); 0074 0075 valid = true; 0076 } 0077 0078 ~TestSetup() 0079 { 0080 } 0081 0082 int countTotalRows(const QModelIndex &parent = {}) const 0083 { 0084 const auto count = collectionView->model()->rowCount(parent); 0085 int total = count; 0086 for (int i = 0; i < count; ++i) { 0087 total += countTotalRows(collectionView->model()->index(i, 0, parent)); 0088 } 0089 return total; 0090 } 0091 0092 static bool unsubscribeCollection(const Collection &col) 0093 { 0094 return modifySubscription({}, {col}); 0095 } 0096 0097 static bool subscribeCollection(const Collection &col) 0098 { 0099 return modifySubscription({col}, {}); 0100 } 0101 0102 static bool modifySubscription(const Collection::List &subscribe, const Collection::List &unsubscribe) 0103 { 0104 auto job = new SubscriptionJob(); 0105 job->subscribe(subscribe); 0106 job->unsubscribe(unsubscribe); 0107 bool ok = false; 0108 [job, &ok]() { 0109 AKVERIFYEXEC(job); 0110 ok = true; 0111 }(); 0112 AKVERIFY(ok); 0113 0114 return true; 0115 } 0116 0117 bool selectCollection(const Collection &col) const 0118 { 0119 AKVERIFY(col.isValid()); 0120 const QModelIndex colIdx = indexForCollection(col); 0121 AKVERIFY(colIdx.isValid()); 0122 0123 collectionView->scrollTo(colIdx); 0124 QTest::mouseClick(collectionView->viewport(), Qt::LeftButton, {}, collectionView->visualRect(colIdx).center()); 0125 0126 AKCOMPARE(collectionView->currentIndex(), colIdx); 0127 return true; 0128 } 0129 0130 bool isCollectionChecked(const Collection &col) const 0131 { 0132 AKVERIFY(col.isValid()); 0133 const auto colIdx = indexForCollection(col); 0134 AKVERIFY(colIdx.isValid()); 0135 0136 return collectionView->model()->data(colIdx, Qt::CheckStateRole).value<Qt::CheckState>() == Qt::Checked; 0137 } 0138 0139 void acceptDialog() const 0140 { 0141 auto button = buttonBox->button(QDialogButtonBox::Ok); 0142 QTest::mouseClick(button, Qt::LeftButton); 0143 } 0144 0145 QModelIndex indexForCollection(const Collection &col) const 0146 { 0147 auto collectionViewModel = collectionView->model(); 0148 std::deque<QModelIndex> idxQueue; 0149 idxQueue.push_back(QModelIndex{}); 0150 while (!idxQueue.empty()) { 0151 const auto idx = idxQueue.front(); 0152 idxQueue.pop_front(); 0153 if (collectionViewModel->data(idx, EntityTreeModel::CollectionIdRole).value<qint64>() == col.id()) { 0154 return idx; 0155 } 0156 for (int i = 0; i < collectionViewModel->rowCount(idx); ++i) { 0157 idxQueue.push_back(collectionViewModel->index(i, 0, idx)); 0158 } 0159 } 0160 return {}; 0161 } 0162 0163 std::unique_ptr<SubscriptionDialog> widget; 0164 QDialogButtonBox *buttonBox = nullptr; 0165 QLineEdit *searchLineEdit = nullptr; 0166 QCheckBox *subscribedOnlyChkBox = nullptr; 0167 QTreeView *collectionView = nullptr; 0168 QPushButton *subscribeButton = nullptr; 0169 QPushButton *unsubscribeButton = nullptr; 0170 SubscriptionModel *model = nullptr; 0171 0172 bool valid = false; 0173 }; 0174 0175 private Q_SLOTS: 0176 void initTestCase() 0177 { 0178 AkonadiTest::checkTestIsIsolated(); 0179 } 0180 0181 void testSearchFilter() 0182 { 0183 TestSetup test; 0184 QVERIFY(test.valid); 0185 0186 QTest::keyClicks(test.searchLineEdit, QStringLiteral("foo")); 0187 QCOMPARE(test.countTotalRows(), 2); 0188 } 0189 0190 void testSubscribedOnlyCheckbox() 0191 { 0192 const auto col = Collection{AkonadiTest::collectionIdFromPath(QStringLiteral("res1/foo/bla"))}; 0193 const AkScopeGuard guard([col]() { 0194 TestSetup::subscribeCollection(col); 0195 }); 0196 0197 QVERIFY(TestSetup::unsubscribeCollection(col)); 0198 0199 TestSetup test; 0200 QVERIFY(test.valid); 0201 0202 test.subscribedOnlyChkBox->setChecked(true); 0203 0204 QTRY_COMPARE(test.countTotalRows(), test.defaultCollectionCount - 1); 0205 0206 test.subscribedOnlyChkBox->setChecked(false); 0207 0208 QTRY_COMPARE(test.countTotalRows(), test.defaultCollectionCount); 0209 } 0210 0211 void testSubscribeButton() 0212 { 0213 const auto col = Collection{AkonadiTest::collectionIdFromPath(QStringLiteral("res1/foo/bla"))}; 0214 const AkScopeGuard guard([col]() { 0215 TestSetup::subscribeCollection(col); 0216 }); 0217 0218 QVERIFY(TestSetup::unsubscribeCollection(col)); 0219 0220 TestSetup test; 0221 QVERIFY(test.valid); 0222 0223 QVERIFY(test.selectCollection(col)); 0224 QTest::mouseClick(test.subscribeButton, Qt::LeftButton); 0225 QVERIFY(test.isCollectionChecked(col)); 0226 0227 auto monitor = AkonadiTest::getTestMonitor(); 0228 QSignalSpy monitorSpy(monitor.get(), &Monitor::collectionSubscribed); 0229 test.acceptDialog(); 0230 QVERIFY(monitorSpy.wait()); 0231 } 0232 0233 void testUnsubscribeButton() 0234 { 0235 const auto col = Collection{AkonadiTest::collectionIdFromPath(QStringLiteral("res1/foo/bla"))}; 0236 0237 TestSetup test; 0238 QVERIFY(test.valid); 0239 0240 QVERIFY(test.selectCollection(col)); 0241 QTest::mouseClick(test.unsubscribeButton, Qt::LeftButton); 0242 QVERIFY(!test.isCollectionChecked(col)); 0243 0244 auto monitor = AkonadiTest::getTestMonitor(); 0245 QSignalSpy monitorSpy(monitor.get(), &Monitor::collectionUnsubscribed); 0246 test.acceptDialog(); 0247 QVERIFY(monitorSpy.wait()); 0248 } 0249 }; 0250 0251 QTEST_AKONADIMAIN(SubscriptionDialogTest) 0252 0253 #include "subscriptiondialogtest.moc"