This includes testing for: - showing folders for the initial resources from the unittest env - creating resources, they should appear in the tree - creating a search folder, should create "Search / search123456" - deleting that search folder, both should disappear, and things shouldn't get corrupted (kitemmodels bug, fix pending, test disabled until KF 5.26) The dummykernel from src/filter/tests is moved up to autotests/ for sharing.wilder
parent
979d027e8f
commit
b74e0adf3e
16 changed files with 292 additions and 2 deletions
@ -0,0 +1,7 @@ |
|||||||
|
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) |
||||||
|
set(KDEPIMLIBS_RUN_ISOLATED_TESTS TRUE) |
||||||
|
set(KDEPIMLIBS_RUN_SQLITE_ISOLATED_TESTS TRUE) |
||||||
|
|
||||||
|
add_akonadi_isolated_test(foldertreewidgettest.cpp) |
||||||
|
target_link_libraries(foldertreewidgettest KF5::Mime KF5::AkonadiWidgets KF5::MailCommon) |
||||||
|
|
||||||
@ -0,0 +1,236 @@ |
|||||||
|
/*
|
||||||
|
Copyright (c) 2016 David Faure <faure@kde.org> |
||||||
|
|
||||||
|
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. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but |
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||||
|
General Public License for more details. |
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along |
||||||
|
with this program; if not, write to the Free Software Foundation, Inc., |
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||||
|
*/ |
||||||
|
|
||||||
|
#undef QT_NO_CAST_FROM_ASCII |
||||||
|
|
||||||
|
#include <qtest_akonadi.h> |
||||||
|
|
||||||
|
#include <AkonadiCore/Item> |
||||||
|
#include <AkonadiCore/Collection> |
||||||
|
#include <AkonadiCore/ItemFetchScope> |
||||||
|
|
||||||
|
#include <AkonadiCore/AgentType> |
||||||
|
#include <AkonadiCore/AgentInstanceCreateJob> |
||||||
|
#include <AkonadiCore/AgentManager> |
||||||
|
#include <AkonadiCore/SearchCreateJob> |
||||||
|
#include <AkonadiCore/SearchQuery> |
||||||
|
#include <AkonadiCore/CollectionDeleteJob> |
||||||
|
#include <AkonadiCore/CollectionCreateJob> |
||||||
|
#include <AkonadiCore/CollectionFetchJob> |
||||||
|
#include <AkonadiCore/EntityOrderProxyModel> |
||||||
|
|
||||||
|
#include <KMime/Message> |
||||||
|
|
||||||
|
#include "folder/entitycollectionorderproxymodel.h" |
||||||
|
#include <MailCommon/FolderTreeWidget> |
||||||
|
#include <MailCommon/FolderTreeView> |
||||||
|
#include <MailCommon/MailKernel> |
||||||
|
|
||||||
|
#include <kitemmodels_version.h> |
||||||
|
|
||||||
|
#include <QTreeView> |
||||||
|
#include <QDebug> |
||||||
|
#include <QEventLoop> |
||||||
|
#include <QLabel> |
||||||
|
#include <QStandardPaths> |
||||||
|
#include <QTest> |
||||||
|
#include <QTemporaryDir> |
||||||
|
|
||||||
|
#include "dummykernel.cpp" |
||||||
|
|
||||||
|
using namespace Akonadi; |
||||||
|
|
||||||
|
class FolderTreeWidgetTest : public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
public: |
||||||
|
|
||||||
|
private slots: |
||||||
|
void initTestCase() |
||||||
|
{ |
||||||
|
AkonadiTest::checkTestIsIsolated(); |
||||||
|
|
||||||
|
DummyKernel *kernel = new DummyKernel(0); |
||||||
|
CommonKernel->registerKernelIf(kernel); |
||||||
|
CommonKernel->registerSettingsIf(kernel); |
||||||
|
|
||||||
|
mFolderTreeWidget = new MailCommon::FolderTreeWidget(0); |
||||||
|
const QStringList resourceOrder{"akonadi_knut_resource_2", "akonadi_knut_resource_0"}; // _1 isn't specified so it goes at the end
|
||||||
|
mFolderTreeWidget->entityOrderProxy()->setTopLevelOrder(resourceOrder); |
||||||
|
|
||||||
|
mCollectionModel = KernelIf->collectionModel(); |
||||||
|
mTopModel = mFolderTreeWidget->folderTreeView()->model(); |
||||||
|
|
||||||
|
// One knut resource is already defined in the unittestenv, so that it's below "Search" in the ETM.
|
||||||
|
QTRY_COMPARE(mCollectionModel->rowCount(), 2); |
||||||
|
QCOMPARE(mTopModel->rowCount(), 1); // Search doesn't appear yet
|
||||||
|
mFolderNames = QStringList{"res1"}; |
||||||
|
QCOMPARE(collectNames(mTopModel), mFolderNames); |
||||||
|
} |
||||||
|
|
||||||
|
void createAndDeleteSearchCollection() // testCreateResources must have been called before
|
||||||
|
{ |
||||||
|
#if KITEMMODELS_VERSION <= QT_VERSION_CHECK(5, 25, 0) |
||||||
|
QSKIP("This test requires a fix in kitemmodels' KRecursiveFilterProxyModel"); |
||||||
|
#endif |
||||||
|
#ifdef SHOW_WIDGET |
||||||
|
mFolderTreeWidget->resize(1000, 1000); |
||||||
|
mFolderTreeWidget->show(); |
||||||
|
#endif |
||||||
|
|
||||||
|
// Create search folder
|
||||||
|
Akonadi::SearchQuery query; |
||||||
|
query.addTerm(Akonadi::SearchTerm(QStringLiteral("plugin"), 1)); |
||||||
|
SearchCreateJob *create = new SearchCreateJob(QStringLiteral("search123456"), query, this); |
||||||
|
create->setSearchMimeTypes({KMime::Message::mimeType()}); |
||||||
|
create->setRemoteSearchEnabled(false); |
||||||
|
AKVERIFYEXEC(create); |
||||||
|
const Collection searchCol = create->createdCollection(); |
||||||
|
QVERIFY(searchCol.isValid()); |
||||||
|
|
||||||
|
// Check it appeared in the tree, under a Search toplevel item
|
||||||
|
QTRY_COMPARE(mCollectionModel->rowCount(), 2); |
||||||
|
QTRY_COMPARE(mTopModel->rowCount(), 2); |
||||||
|
const QStringList names = collectNames(mTopModel); |
||||||
|
QCOMPARE(names, QStringList() << "res1" << "Search"); |
||||||
|
const int rowOfSearch = names.indexOf("Search"); |
||||||
|
const QModelIndex searchParent = mTopModel->index(rowOfSearch, 0); |
||||||
|
QCOMPARE(mTopModel->rowCount(searchParent), 1); // the actual child search folder
|
||||||
|
|
||||||
|
#ifdef SHOW_WIDGET |
||||||
|
QTest::qWait(500); |
||||||
|
#endif |
||||||
|
|
||||||
|
QSignalSpy rATBRSpy_CollectionModel(mCollectionModel, &QAbstractItemModel::rowsAboutToBeRemoved); |
||||||
|
QSignalSpy rATBRSpy_FolderTreeProxyModel(mFolderTreeWidget->folderTreeWidgetProxyModel(), &QAbstractItemModel::rowsAboutToBeRemoved); |
||||||
|
QSignalSpy rATBRSpy_TopModel(mTopModel, &QAbstractItemModel::rowsAboutToBeRemoved); |
||||||
|
|
||||||
|
// Now delete it
|
||||||
|
Akonadi::CollectionDeleteJob *delJob = new Akonadi::CollectionDeleteJob(searchCol); |
||||||
|
AKVERIFYEXEC(delJob); |
||||||
|
|
||||||
|
// Check it disappeared from the tree, as well as the toplevel item
|
||||||
|
QTRY_COMPARE(mTopModel->rowCount(), 1); |
||||||
|
QCOMPARE(collectNames(mTopModel), mFolderNames); |
||||||
|
QCOMPARE(collectNames(mFolderTreeWidget->entityOrderProxy()), mFolderNames); |
||||||
|
|
||||||
|
QCOMPARE(rATBRSpy_CollectionModel.count(), 2); // one for the child, one for the parent
|
||||||
|
QCOMPARE(rATBRSpy_FolderTreeProxyModel.count(), 2); // one for the child, one for the parent
|
||||||
|
QCOMPARE(rATBRSpy_TopModel.count(), 2); // one for the child, one for the parent
|
||||||
|
|
||||||
|
checkMailFolders(mTopModel->index(0, 0)); |
||||||
|
|
||||||
|
#ifdef SHOW_WIDGET |
||||||
|
QTest::qWait(1000); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
void testCreateResources() |
||||||
|
{ |
||||||
|
// Test creating more knut resources.
|
||||||
|
// This tests that ETM and proxies on top update correctly, and it tests toplevel collection order.
|
||||||
|
const QVector<int> numFolders{ 1, 5, 2 }; |
||||||
|
QVector<Collection> topLevelCollections; |
||||||
|
const AgentType agentType = AgentManager::self()->type(QStringLiteral("akonadi_knut_resource")); |
||||||
|
QVERIFY(agentType.isValid()); |
||||||
|
mFolderNames = QStringList{"res3", "res1", "res2"}; // according to resourceOrder above (the folder names are defined in testdata-res*.xml)
|
||||||
|
|
||||||
|
// Create resources
|
||||||
|
const int numResources = numFolders.count(); |
||||||
|
for (int i = 1 /*first one already created*/ ; i < numResources ; ++i ) { |
||||||
|
AgentInstanceCreateJob *agentCreateJob = new AgentInstanceCreateJob(agentType); |
||||||
|
AKVERIFYEXEC(agentCreateJob); |
||||||
|
const QString identifier = agentCreateJob->instance().identifier(); |
||||||
|
|
||||||
|
QTRY_COMPARE(mCollectionModel->rowCount(), i + 1); |
||||||
|
QTRY_COMPARE(mTopModel->rowCount(), i + 1); |
||||||
|
|
||||||
|
Collection topLevelCollection; |
||||||
|
QTRY_VERIFY((topLevelCollection = topLevelCollectionForResource(identifier)).isValid()); |
||||||
|
topLevelCollections.append(topLevelCollection); |
||||||
|
|
||||||
|
// Now create some folders
|
||||||
|
for (int number = 0 ; number < numFolders[i] ; ++number) { |
||||||
|
Collection mailCollection; |
||||||
|
mailCollection.setParentCollection(topLevelCollection); |
||||||
|
mailCollection.setName(QStringLiteral("mailCollection_%1_%2").arg(i).arg(number)); |
||||||
|
CollectionCreateJob *collCreateJob = new CollectionCreateJob(mailCollection); |
||||||
|
AKVERIFYEXEC(collCreateJob); |
||||||
|
} |
||||||
|
const int resourceRow = collectNames(mTopModel).indexOf("res" + QString::number(i+1)); |
||||||
|
QModelIndex parent = mTopModel->index(resourceRow, 0); |
||||||
|
QTRY_COMPARE(mTopModel->rowCount(parent), numFolders[i]); |
||||||
|
|
||||||
|
checkMailFolders(parent); |
||||||
|
} |
||||||
|
QCOMPARE(collectNames(mTopModel), mFolderNames); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
static Collection topLevelCollectionForResource(const QString &identifier) |
||||||
|
{ |
||||||
|
// Find out the collection for the resource (as defined in unittestenv/xdglocal/testdata-res*.xml)
|
||||||
|
CollectionFetchJob *job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::FirstLevel); |
||||||
|
if (job->exec()) { |
||||||
|
const Collection::List collections = job->collections(); |
||||||
|
foreach (const Collection &col, collections) { |
||||||
|
//qDebug() << col.resource() << col.mimeType();
|
||||||
|
if (col.resource() == identifier) { |
||||||
|
return col; |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
qWarning() << job->errorString(); |
||||||
|
} |
||||||
|
return Collection(); |
||||||
|
} |
||||||
|
|
||||||
|
// Check that every child of @p parent has a valid CollectionRole.
|
||||||
|
static void checkMailFolders(const QModelIndex &parent) |
||||||
|
{ |
||||||
|
const QAbstractItemModel *model = parent.model(); |
||||||
|
for (int row = 0; row < model->rowCount(parent); ++row) { |
||||||
|
QModelIndex idx = model->index(row, 0, parent); |
||||||
|
QModelIndex col1idx = model->index(row, 1, parent); |
||||||
|
QCOMPARE(col1idx.sibling(col1idx.row(), 0), idx); |
||||||
|
Collection collection = idx.data(EntityTreeModel::CollectionRole).value<Collection>(); |
||||||
|
QVERIFY2(collection.isValid(), qPrintable(idx.data().toString())); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
static QStringList collectNames(QAbstractItemModel *model); |
||||||
|
EntityMimeTypeFilterModel *mCollectionModel; |
||||||
|
QAbstractItemModel *mTopModel; |
||||||
|
MailCommon::FolderTreeWidget *mFolderTreeWidget; |
||||||
|
QStringList mFolderNames; |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
QStringList FolderTreeWidgetTest::collectNames(QAbstractItemModel *model) |
||||||
|
{ |
||||||
|
QStringList ret; |
||||||
|
for (int row = 0 ; row < model->rowCount() ; ++row) { |
||||||
|
ret.append(model->index(row, 0).data().toString()); |
||||||
|
} |
||||||
|
return ret; |
||||||
|
} |
||||||
|
|
||||||
|
QTEST_AKONADIMAIN(FolderTreeWidgetTest) |
||||||
|
|
||||||
|
#include "foldertreewidgettest.moc" |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
<config> |
||||||
|
<kdehome>kdehome</kdehome> |
||||||
|
<confighome>xdgconfig-sqlite.db</confighome> |
||||||
|
<datahome>xdglocal</datahome> |
||||||
|
<agent synchronize="true">akonadi_knut_resource</agent> |
||||||
|
<envvar name="AKONADI_DISABLE_AGENT_AUTOSTART">true</envvar> |
||||||
|
<envvar name="TESTRUNNER_DB_ENVIRONMENT">sqlite</envvar> |
||||||
|
</config> |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
[%General] |
||||||
|
# This is a slightly adjusted version of the QSQLITE driver from Qt |
||||||
|
# It is provided by akonadi itself |
||||||
|
Driver=QSQLITE3 |
||||||
|
|
||||||
|
[Debug] |
||||||
|
Tracer=null |
||||||
|
|
||||||
|
[Search] |
||||||
|
Manager=Dummy |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
[ProcessedDefaults] |
||||||
|
defaultaddressbook=done |
||||||
|
defaultcalendar=done |
||||||
|
defaultnotebook=done |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
[General] |
||||||
|
DataFile[$e]=$XDG_DATA_HOME/testdata-res1.xml |
||||||
|
FileWatchingEnabled=false |
||||||
|
|
||||||
@ -0,0 +1,4 @@ |
|||||||
|
[General] |
||||||
|
DataFile[$e]=$XDG_DATA_HOME/testdata-res2.xml |
||||||
|
FileWatchingEnabled=false |
||||||
|
|
||||||
@ -0,0 +1,4 @@ |
|||||||
|
[General] |
||||||
|
DataFile[$e]=$XDG_DATA_HOME/testdata-res3.xml |
||||||
|
FileWatchingEnabled=false |
||||||
|
|
||||||
@ -0,0 +1,4 @@ |
|||||||
|
<knut> |
||||||
|
<collection rid="6" name="res1" content="inode/directory,message/rfc822"> |
||||||
|
</collection> |
||||||
|
</knut> |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
<knut> |
||||||
|
<collection rid="2" name="res2" content="inode/directory,message/rfc822"> |
||||||
|
</collection> |
||||||
|
</knut> |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
<knut> |
||||||
|
<collection rid="3" name="res3" content="inode/directory,message/rfc822"> |
||||||
|
</collection> |
||||||
|
</knut> |
||||||
Loading…
Reference in new issue