File indexing completed on 2024-11-10 04:40:11
0001 /* 0002 SPDX-FileCopyrightText: 2013 Christian Mollekopf <mollekopf@kolabsys.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "changerecorder_p.h" 0008 #include "collectioncreatejob.h" 0009 #include "control.h" 0010 #include "entitytreemodel.h" 0011 #include "entitytreemodel_p.h" 0012 #include "favoritecollectionsmodel.h" 0013 #include "itemcreatejob.h" 0014 #include "monitor_p.h" 0015 #include "qtest_akonadi.h" 0016 0017 #include <KConfigGroup> 0018 #include <KSharedConfig> 0019 0020 #include <QObject> 0021 #include <QSortFilterProxyModel> 0022 0023 using namespace Akonadi; 0024 0025 class InspectableETM : public EntityTreeModel 0026 { 0027 public: 0028 explicit InspectableETM(ChangeRecorder *monitor, QObject *parent = nullptr) 0029 : EntityTreeModel(monitor, parent) 0030 { 0031 } 0032 EntityTreeModelPrivate *etmPrivate() 0033 { 0034 return d_ptr.get(); 0035 } 0036 void reset() 0037 { 0038 beginResetModel(); 0039 endResetModel(); 0040 } 0041 }; 0042 0043 class FavoriteProxyTest : public QObject 0044 { 0045 Q_OBJECT 0046 0047 private Q_SLOTS: 0048 void initTestCase(); 0049 void testItemAdded(); 0050 void testLoadConfig(); 0051 void testInsertAfterModelCreation(); 0052 0053 private: 0054 InspectableETM *createETM(); 0055 }; 0056 0057 void FavoriteProxyTest::initTestCase() 0058 { 0059 AkonadiTest::checkTestIsIsolated(); 0060 Akonadi::Control::start(); 0061 AkonadiTest::setAllResourcesOffline(); 0062 } 0063 0064 QModelIndex getIndex(const QString &string, EntityTreeModel *model) 0065 { 0066 QModelIndexList list = model->match(model->index(0, 0), Qt::DisplayRole, string, 1, Qt::MatchRecursive); 0067 if (list.isEmpty()) { 0068 return QModelIndex(); 0069 } 0070 return list.first(); 0071 } 0072 0073 /** 0074 * Since we have no sensible way to figure out if the model is fully populated, 0075 * we use the brute force approach. 0076 */ 0077 bool waitForPopulation(const QModelIndex &idx, EntityTreeModel *model, int count) 0078 { 0079 for (int i = 0; i < 500; i++) { 0080 if (model->rowCount(idx) >= count) { 0081 return true; 0082 } 0083 QTest::qWait(10); 0084 } 0085 return false; 0086 } 0087 0088 InspectableETM *FavoriteProxyTest::createETM() 0089 { 0090 auto changeRecorder = new ChangeRecorder(this); 0091 changeRecorder->setCollectionMonitored(Collection::root()); 0092 AkonadiTest::akWaitForSignal(changeRecorder, &Monitor::monitorReady); 0093 auto model = new InspectableETM(changeRecorder, this); 0094 model->setItemPopulationStrategy(Akonadi::EntityTreeModel::LazyPopulation); 0095 return model; 0096 } 0097 0098 /** 0099 * Tests that the item is being referenced when added to the favorite proxy, and dereferenced when removed. 0100 */ 0101 void FavoriteProxyTest::testItemAdded() 0102 { 0103 Collection res3 = Collection(AkonadiTest::collectionIdFromPath(QStringLiteral("res3"))); 0104 0105 InspectableETM *model = createETM(); 0106 0107 KConfigGroup configGroup(KSharedConfig::openConfig(), QStringLiteral("favoritecollectionsmodeltest")); 0108 0109 auto favoriteModel = new FavoriteCollectionsModel(model, configGroup, this); 0110 0111 const int numberOfRootCollections = 4; 0112 // Wait for initial listing to complete 0113 QVERIFY(waitForPopulation(QModelIndex(), model, numberOfRootCollections)); 0114 0115 const QModelIndex res3Index = getIndex(QStringLiteral("res3"), model); 0116 QVERIFY(res3Index.isValid()); 0117 0118 const auto favoriteCollection = res3Index.data(EntityTreeModel::CollectionRole).value<Akonadi::Collection>(); 0119 QVERIFY(favoriteCollection.isValid()); 0120 0121 QVERIFY(!model->etmPrivate()->isMonitored(favoriteCollection.id())); 0122 0123 // Ensure the collection is reference counted after being added to the favorite model 0124 { 0125 favoriteModel->addCollection(favoriteCollection); 0126 // the collection is in the favorites model 0127 QTRY_COMPARE(favoriteModel->rowCount(QModelIndex()), 1); 0128 QTRY_COMPARE(favoriteModel->data(favoriteModel->index(0, 0, QModelIndex()), EntityTreeModel::CollectionIdRole).value<Akonadi::Collection::Id>(), 0129 favoriteCollection.id()); 0130 // the collection got referenced 0131 QTRY_VERIFY(model->etmPrivate()->isMonitored(favoriteCollection.id())); 0132 // the collection is not yet buffered though 0133 QTRY_VERIFY(!model->etmPrivate()->isBuffered(favoriteCollection.id())); 0134 } 0135 0136 // Survive a reset 0137 { 0138 QSignalSpy resetSpy(model, &QAbstractItemModel::modelReset); 0139 model->reset(); 0140 QTRY_COMPARE(resetSpy.count(), 1); 0141 // the collection is in the favorites model 0142 QTRY_COMPARE(favoriteModel->rowCount(QModelIndex()), 1); 0143 QTRY_COMPARE(favoriteModel->data(favoriteModel->index(0, 0, QModelIndex()), EntityTreeModel::CollectionIdRole).value<Akonadi::Collection::Id>(), 0144 favoriteCollection.id()); 0145 // the collection got referenced 0146 QTRY_VERIFY(model->etmPrivate()->isMonitored(favoriteCollection.id())); 0147 // the collection is not yet buffered though 0148 QTRY_VERIFY(!model->etmPrivate()->isBuffered(favoriteCollection.id())); 0149 } 0150 0151 // Ensure the collection is no longer reference counted after being added to the favorite model, and moved to the buffer 0152 { 0153 favoriteModel->removeCollection(favoriteCollection); 0154 // moved from being reference counted to being buffered 0155 QTRY_VERIFY(model->etmPrivate()->isBuffered(favoriteCollection.id())); 0156 QTRY_COMPARE(favoriteModel->rowCount(QModelIndex()), 0); 0157 } 0158 } 0159 0160 void FavoriteProxyTest::testLoadConfig() 0161 { 0162 InspectableETM *model = createETM(); 0163 0164 const int numberOfRootCollections = 4; 0165 // Wait for initial listing to complete 0166 QVERIFY(waitForPopulation(QModelIndex(), model, numberOfRootCollections)); 0167 const QModelIndex res3Index = getIndex(QStringLiteral("res3"), model); 0168 QVERIFY(res3Index.isValid()); 0169 const auto favoriteCollection = res3Index.data(EntityTreeModel::CollectionRole).value<Akonadi::Collection>(); 0170 QVERIFY(favoriteCollection.isValid()); 0171 0172 KConfigGroup configGroup(KSharedConfig::openConfig(), QStringLiteral("favoritecollectionsmodeltest")); 0173 configGroup.writeEntry("FavoriteCollectionIds", QList<Akonadi::Collection::Id>() << favoriteCollection.id()); 0174 configGroup.writeEntry("FavoriteCollectionLabels", QStringList() << QStringLiteral("label1")); 0175 0176 auto favoriteModel = new FavoriteCollectionsModel(model, configGroup, this); 0177 0178 { 0179 QTRY_COMPARE(favoriteModel->rowCount(QModelIndex()), 1); 0180 QTRY_COMPARE(favoriteModel->data(favoriteModel->index(0, 0, QModelIndex()), EntityTreeModel::CollectionIdRole).value<Akonadi::Collection::Id>(), 0181 favoriteCollection.id()); 0182 // the collection got referenced 0183 QTRY_VERIFY(model->etmPrivate()->isMonitored(favoriteCollection.id())); 0184 } 0185 } 0186 0187 class Filter : public QSortFilterProxyModel 0188 { 0189 public: 0190 bool filterAcceptsRow(int /*source_row*/, const QModelIndex & /*source_parent*/) const override 0191 { 0192 return accepts; 0193 } 0194 bool accepts; 0195 }; 0196 0197 void FavoriteProxyTest::testInsertAfterModelCreation() 0198 { 0199 InspectableETM *model = createETM(); 0200 Filter filter; 0201 filter.accepts = false; 0202 filter.setSourceModel(model); 0203 0204 const int numberOfRootCollections = 4; 0205 // Wait for initial listing to complete 0206 QVERIFY(waitForPopulation(QModelIndex(), model, numberOfRootCollections)); 0207 const QModelIndex res3Index = getIndex(QStringLiteral("res3"), model); 0208 QVERIFY(res3Index.isValid()); 0209 const auto favoriteCollection = res3Index.data(EntityTreeModel::CollectionRole).value<Akonadi::Collection>(); 0210 QVERIFY(favoriteCollection.isValid()); 0211 0212 KConfigGroup configGroup(KSharedConfig::openConfig(), QStringLiteral("favoritecollectionsmodeltest2")); 0213 0214 auto favoriteModel = new FavoriteCollectionsModel(&filter, configGroup, this); 0215 0216 // Make sure the filter is not letting anything through 0217 QTest::qWait(0); 0218 QCOMPARE(filter.rowCount(QModelIndex()), 0); 0219 0220 // The collection is not in the model yet 0221 favoriteModel->addCollection(favoriteCollection); 0222 filter.accepts = true; 0223 filter.invalidate(); 0224 0225 { 0226 QTRY_COMPARE(favoriteModel->rowCount(QModelIndex()), 1); 0227 QTRY_COMPARE(favoriteModel->data(favoriteModel->index(0, 0, QModelIndex()), EntityTreeModel::CollectionIdRole).value<Akonadi::Collection::Id>(), 0228 favoriteCollection.id()); 0229 // the collection got referenced 0230 QTRY_VERIFY(model->etmPrivate()->isMonitored(favoriteCollection.id())); 0231 } 0232 } 0233 0234 #include "favoriteproxytest.moc" 0235 0236 QTEST_AKONADIMAIN(FavoriteProxyTest)