Add unittest for FolderTreeWidget.

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
David Faure 10 years ago
parent 979d027e8f
commit b74e0adf3e
  1. 1
      CMakeLists.txt
  2. 7
      autotests/CMakeLists.txt
  3. 0
      autotests/dummykernel.cpp
  4. 0
      autotests/dummykernel.h
  5. 236
      autotests/foldertreewidgettest.cpp
  6. 8
      autotests/unittestenv/config-sqlite-db.xml
  7. 10
      autotests/unittestenv/xdgconfig-sqlite.db/akonadi/akonadiserverrc
  8. 4
      autotests/unittestenv/xdgconfig/akonadi-firstrunrc
  9. 4
      autotests/unittestenv/xdgconfig/akonadi_knut_resource_0rc
  10. 4
      autotests/unittestenv/xdgconfig/akonadi_knut_resource_1rc
  11. 4
      autotests/unittestenv/xdgconfig/akonadi_knut_resource_2rc
  12. 4
      autotests/unittestenv/xdglocal/testdata-res1.xml
  13. 4
      autotests/unittestenv/xdglocal/testdata-res2.xml
  14. 4
      autotests/unittestenv/xdglocal/testdata-res3.xml
  15. 2
      src/filter/tests/CMakeLists.txt
  16. 2
      src/filter/tests/kmfilterdialogtestgui.cpp

@ -112,5 +112,6 @@ install(FILES
)
add_subdirectory(src)
add_subdirectory(autotests)
install( FILES mailcommon.categories DESTINATION ${KDE_INSTALL_CONFDIR} )
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)

@ -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>

@ -30,7 +30,7 @@ target_link_libraries(mndadvicedialoggui
)
set(kmfilterdialogtestgui_SRCS kmfilterdialogtestgui.cpp dummykernel.cpp)
set(kmfilterdialogtestgui_SRCS kmfilterdialogtestgui.cpp ../../../autotests/dummykernel.cpp)
add_executable(kmfilterdialogtestgui ${kmfilterdialogtestgui_SRCS})
ecm_mark_as_test(kmfilterdialogtestgui)
target_link_libraries(kmfilterdialogtestgui

@ -16,7 +16,7 @@
*/
#include "kmfilterdialogtestgui.h"
#include "dummykernel.h"
#include "../../../autotests/dummykernel.h"
#include "../kernel/mailkernel.h"
#include "../kmfilterdialog.h"

Loading…
Cancel
Save