diff options
author | Hannah von Reth <hannah.vonreth@owncloud.com> | 2021-07-02 11:21:01 +0300 |
---|---|---|
committer | Hannah von Reth <vonreth@kde.org> | 2021-07-13 11:14:00 +0300 |
commit | 3f5163a4f30cf5978ffd7ee363e0d81065eb29c0 (patch) | |
tree | 43be5adbc8934993f79df4fa931d07450dae7dfe | |
parent | f1ee3e18e858cd2816dbf588e35cb7f1441f8511 (diff) |
Delay the deletion of Folder objects
This removes the need to check for the existance of the pointers
Fixes: #8690
41 files changed, 288 insertions, 222 deletions
diff --git a/src/gui/folder.h b/src/gui/folder.h index 5c34b90e5..7b3103985 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -124,10 +124,6 @@ public: Folder(const FolderDefinition &definition, AccountState *accountState, std::unique_ptr<Vfs> vfs, QObject *parent = nullptr); ~Folder() override; - - typedef QMap<QString, Folder *> Map; - typedef QMapIterator<QString, Folder *> MapIterator; - /** * The account the folder is configured on. */ diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 58e6bdff5..92f9659f7 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -95,21 +95,14 @@ FolderMan::~FolderMan() _instance = nullptr; } -const OCC::Folder::Map &FolderMan::map() const +const QMap<QString, Folder *> &FolderMan::map() const { return _folderMap; } -QList<Folder *> FolderMan::list() const -{ - return _folderMap.values(); -} - void FolderMan::unloadFolder(Folder *f) { - if (!f) { - return; - } + Q_ASSERT(f); _socketApi->slotUnregisterPath(f->alias()); @@ -129,28 +122,19 @@ void FolderMan::unloadFolder(Folder *f) &f->syncEngine().syncFileStatusTracker(), &SyncFileStatusTracker::slotPathTouched); } -int FolderMan::unloadAndDeleteAllFolders() +void FolderMan::unloadAndDeleteAllFolders() { - int cnt = 0; - // clear the list of existing folders. - Folder::MapIterator i(_folderMap); - while (i.hasNext()) { - i.next(); - Folder *f = i.value(); - unloadFolder(f); - delete f; - cnt++; + const auto folders = std::move(_folderMap); + for (auto *folder : folders) { + _socketApi->slotUnregisterPath(folder->alias()); + folder->deleteLater(); } - OC_ASSERT(_folderMap.isEmpty()); - _lastSyncFolder = nullptr; _currentSyncFolder = nullptr; _scheduledFolders.clear(); emit folderListChanged(_folderMap); emit scheduleQueueChanged(); - - return cnt; } void FolderMan::registerFolderWithSocketApi(Folder *folder) @@ -704,7 +688,7 @@ void FolderMan::setSyncEnabled(bool enabled) } _syncEnabled = enabled; // force a redraw in case the network connect status changed - emit(folderSyncStateChange(nullptr)); + Q_EMIT folderSyncStateChange(nullptr); } void FolderMan::startScheduledSyncSoon() @@ -825,16 +809,14 @@ void FolderMan::slotEtagPollTimerTimeout() void FolderMan::slotRemoveFoldersForAccount(AccountState *accountState) { - QVarLengthArray<Folder *, 16> foldersToRemove; - Folder::MapIterator i(_folderMap); - while (i.hasNext()) { - i.next(); - Folder *folder = i.value(); + QList<Folder *> foldersToRemove; + // reserve a magic number + foldersToRemove.reserve(16); + for (auto *folder : qAsConst(_folderMap)) { if (folder->accountState() == accountState) { foldersToRemove.append(folder); } } - for (const auto &f : foldersToRemove) { removeFolder(f); } @@ -1128,13 +1110,13 @@ void FolderMan::removeFolder(Folder *f) // Let the folder delete itself when done. connect(f, &Folder::syncFinished, f, &QObject::deleteLater); } else { - delete f; + f->deleteLater(); } #ifdef Q_OS_WIN _navigationPaneHelper.scheduleUpdateCloudStorageRegistry(); #endif - + Q_EMIT folderRemoved(f); emit folderListChanged(_folderMap); } diff --git a/src/gui/folderman.h b/src/gui/folderman.h index 0a639c314..c137378c8 100644 --- a/src/gui/folderman.h +++ b/src/gui/folderman.h @@ -25,9 +25,11 @@ #include "navigationpanehelper.h" #include "syncfileitem.h" -class TestFolderMan; - namespace OCC { +namespace TestUtils { + // prototype for test friend + FolderMan *folderMan(); +} class Application; class SyncResult; @@ -99,8 +101,7 @@ public: */ static void backwardMigrationSettingsKeys(QStringList *deleteKeys, QStringList *ignoreKeys); - const Folder::Map &map() const; - QList<Folder *> list() const; + const QMap<QString, Folder *> &map() const; /** Adds a folder for an account, ensures the journal is gone and saves it in the settings. */ @@ -216,7 +217,7 @@ public: bool isAnySyncRunning() const; /** Removes all folders */ - int unloadAndDeleteAllFolders(); + void unloadAndDeleteAllFolders(); /** * If enabled is set to false, no new folders will start to sync. @@ -252,7 +253,8 @@ signals: /** * Emitted whenever the list of configured folders changes. */ - void folderListChanged(const Folder::Map &); + void folderListChanged(const QMap<QString, Folder *> &); + void folderRemoved(Folder *folder); public slots: @@ -341,7 +343,7 @@ private: void setupFoldersHelper(QSettings &settings, AccountStatePtr account, const QStringList &ignoreKeys, bool backwardsCompatible, bool foldersWithPlaceholders); QSet<Folder *> _disabledFolders; - Folder::Map _folderMap; + QMap<QString, Folder *> _folderMap; QString _folderConfigPath; Folder *_currentSyncFolder; QPointer<Folder> _lastSyncFolder; @@ -377,7 +379,7 @@ private: static FolderMan *_instance; explicit FolderMan(QObject *parent = nullptr); friend class OCC::Application; - friend class ::TestFolderMan; + friend OCC::FolderMan *OCC::TestUtils::folderMan(); }; } // namespace OCC diff --git a/src/gui/folderwatcher_win.cpp b/src/gui/folderwatcher_win.cpp index fd20725bd..4541c895a 100644 --- a/src/gui/folderwatcher_win.cpp +++ b/src/gui/folderwatcher_win.cpp @@ -216,10 +216,8 @@ FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p, const QString &path : _parent(p) { _thread = new WatcherThread(path); - connect(_thread, SIGNAL(changed(const QString &)), - _parent, SLOT(changeDetected(const QString &))); - connect(_thread, SIGNAL(lostChanges()), - _parent, SIGNAL(lostChanges())); + connect(_thread, &WatcherThread::changed, _parent, qOverload<const QString &>(&FolderWatcher::changeDetected)); + connect(_thread, &WatcherThread::lostChanges, _parent, &FolderWatcher::lostChanges); connect(_thread, &WatcherThread::ready, this, [this]() { _ready = 1; }); _thread->start(); diff --git a/src/gui/folderwizard.cpp b/src/gui/folderwizard.cpp index e481333d8..35c44c69b 100644 --- a/src/gui/folderwizard.cpp +++ b/src/gui/folderwizard.cpp @@ -424,10 +424,7 @@ bool FolderWizardRemotePath::isComplete() const } wizard()->setProperty("targetPath", dir); - Folder::Map map = FolderMan::instance()->map(); - Folder::Map::const_iterator i = map.constBegin(); - for (i = map.constBegin(); i != map.constEnd(); i++) { - Folder *f = static_cast<Folder *>(i.value()); + for (auto *f : qAsConst(FolderMan::instance()->map())) { if (f->accountState()->account() != _account) { continue; } diff --git a/src/gui/folderwizard.h b/src/gui/folderwizard.h index 251f4afd2..f0b4e42e8 100644 --- a/src/gui/folderwizard.h +++ b/src/gui/folderwizard.h @@ -58,14 +58,12 @@ public: bool isComplete() const override; void initializePage() override; void cleanupPage() override; - - void setFolderMap(const Folder::Map &fm) { _folderMap = fm; } protected slots: void slotChooseLocalFolder(); private: Ui_FolderWizardSourcePage _ui; - Folder::Map _folderMap; + QMap<QString, Folder *> _folderMap; AccountPtr _account; }; diff --git a/src/gui/issueswidget.cpp b/src/gui/issueswidget.cpp index 0b801115f..99d622d19 100644 --- a/src/gui/issueswidget.cpp +++ b/src/gui/issueswidget.cpp @@ -84,14 +84,12 @@ IssuesWidget::IssuesWidget(QWidget *parent) header->setExpandingColumn(static_cast<int>(ProtocolItemModel::ProtocolItemRole::Action)); header->setSortIndicator(static_cast<int>(ProtocolItemModel::ProtocolItemRole::Time), Qt::DescendingOrder); - connect(_ui->_tableView, &QTreeView::customContextMenuRequested, this, &IssuesWidget::slotItemContextMenu); _ui->_tableView->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); connect(header, &QHeaderView::customContextMenuRequested, header, [header, this] { ProtocolWidget::showHeaderContextMenu(header, _sortModel); }); - _ui->_tooManyIssuesWarning->hide(); connect(_model, &ProtocolItemModel::rowsInserted, this, [this] { _ui->_tooManyIssuesWarning->setVisible(_model->isModelFull()); @@ -104,6 +102,12 @@ IssuesWidget::IssuesWidget(QWidget *parent) _ui->_conflictHelp->setText( tr("There were conflicts. <a href=\"%1\">Check the documentation on how to resolve them.</a>") .arg(Theme::instance()->conflictHelpUrl())); + + connect(FolderMan::instance(), &FolderMan::folderRemoved, this, [this](Folder *f) { + _model->remove_if([f](const ProtocolItem &item) { + return item.folder() == f; + }); + }); } IssuesWidget::~IssuesWidget() @@ -122,7 +126,7 @@ void IssuesWidget::slotProgressInfo(const QString &folder, const ProgressInfo &p const auto &engine = f->syncEngine(); const auto style = engine.lastLocalDiscoveryStyle(); _model->remove_if([&](const ProtocolItem &item) { - if (item.folderName() != folder) { + if (item.folder()->path() != folder) { return false; } if (style == LocalDiscoveryStyle::FilesystemOnly) { @@ -148,7 +152,7 @@ void IssuesWidget::slotProgressInfo(const QString &folder, const ProgressInfo &p // Inform other components about them. QStringList conflicts; for (const auto &data : _model->rawData()) { - if (data.folderName() == folder + if (data.folder()->path() == folder && data.status() == SyncFileItem::Conflict) { conflicts.append(data.path()); } diff --git a/src/gui/models/protocolitemmodel.cpp b/src/gui/models/protocolitemmodel.cpp index 0ecc7cdd1..76f5c557a 100644 --- a/src/gui/models/protocolitemmodel.cpp +++ b/src/gui/models/protocolitemmodel.cpp @@ -22,15 +22,6 @@ #include <QIcon> -namespace { -auto getFolder(const OCC::ProtocolItem &item) -{ - auto f = OCC::FolderMan::instance()->folder(item.folderName()); - OC_ASSERT(f); - return f; -} -} - using namespace OCC; ProtocolItemModel::ProtocolItemModel(QObject *parent, bool issueMode) @@ -69,7 +60,7 @@ QVariant ProtocolItemModel::data(const QModelIndex &index, int role) const case ProtocolItemRole::Time: return item.timestamp(); case ProtocolItemRole::Folder: - return getFolder(item)->shortGuiLocalPath(); + return item.folder()->shortGuiLocalPath(); case ProtocolItemRole::Action: return item.message(); case ProtocolItemRole::Size: @@ -77,7 +68,7 @@ QVariant ProtocolItemModel::data(const QModelIndex &index, int role) const case ProtocolItemRole::File: return Utility::fileNameForGuiUse(item.path()); case ProtocolItemRole::Account: - return getFolder(item)->accountState()->account()->displayName(); + return item.folder()->accountState()->account()->displayName(); case ProtocolItemRole::ColumnCount: Q_UNREACHABLE(); break; @@ -105,7 +96,7 @@ QVariant ProtocolItemModel::data(const QModelIndex &index, int role) const case ProtocolItemRole::Time: return item.timestamp(); case ProtocolItemRole::Folder: - return item.folderName(); + return item.folder()->path(); case ProtocolItemRole::Action: return item.message(); case ProtocolItemRole::Size: @@ -113,7 +104,7 @@ QVariant ProtocolItemModel::data(const QModelIndex &index, int role) const case ProtocolItemRole::File: return item.path(); case ProtocolItemRole::Account: - return getFolder(item)->accountState()->account()->displayName(); + return item.folder()->accountState()->account()->displayName(); case ProtocolItemRole::ColumnCount: Q_UNREACHABLE(); break; diff --git a/src/gui/protocolitem.cpp b/src/gui/protocolitem.cpp index 769236005..cc7ed5c40 100644 --- a/src/gui/protocolitem.cpp +++ b/src/gui/protocolitem.cpp @@ -13,6 +13,7 @@ */ #include "protocolitem.h" +#include "folderman.h" #include "progressdispatcher.h" #include <QApplication> @@ -20,11 +21,12 @@ #include <QMenu> #include <QPointer> + using namespace OCC; ProtocolItem::ProtocolItem(const QString &folder, const SyncFileItemPtr &item) : _path(item->destination()) - , _folderName(folder) + , _folder(FolderMan::instance()->folder(folder)) , _size(item->_size) , _status(item->_status) , _direction(item->_direction) @@ -46,9 +48,9 @@ QString ProtocolItem::path() const return _path; } -QString ProtocolItem::folderName() const +Folder *ProtocolItem::folder() const { - return _folderName; + return _folder; } QDateTime ProtocolItem::timestamp() const diff --git a/src/gui/protocolitem.h b/src/gui/protocolitem.h index ab2ee44e0..8f064a1aa 100644 --- a/src/gui/protocolitem.h +++ b/src/gui/protocolitem.h @@ -13,6 +13,8 @@ */ #pragma once +#include "folder.h" + #include "csync/csync.h" #include "libsync/syncfileitem.h" @@ -29,7 +31,7 @@ public: QString path() const; - QString folderName() const; + Folder *folder() const; QDateTime timestamp() const; @@ -45,7 +47,7 @@ public: private: QString _path; - QString _folderName; + Folder *_folder; QDateTime _timestamp; qint64 _size; SyncFileItem::Status _status BITFIELD(4); @@ -53,6 +55,8 @@ private: QString _message; bool _sizeIsRelevant; + + friend class TestProtocolModel; }; } diff --git a/src/gui/protocolwidget.cpp b/src/gui/protocolwidget.cpp index c8f674938..c39c44386 100644 --- a/src/gui/protocolwidget.cpp +++ b/src/gui/protocolwidget.cpp @@ -64,8 +64,11 @@ ProtocolWidget::ProtocolWidget(QWidget *parent) showHeaderContextMenu(header, _sortModel); }); - - _ui->_headerLabel->setText(tr("Local sync protocol")); + connect(FolderMan::instance(), &FolderMan::folderRemoved, this, [this](Folder *f) { + _model->remove_if([f](const ProtocolItem &item) { + return item.folder() == f; + }); + }); } ProtocolWidget::~ProtocolWidget() @@ -92,22 +95,19 @@ void ProtocolWidget::showContextMenu(QWidget *parent, ProtocolItemModel *model, if (items.size() == 1) { const auto &data = model->protocolItem(items.first()); - auto folder = FolderMan::instance()->folder(data.folderName()); - if (folder) { - { - const QString localPath = folder->path() + data.path(); - if (QFileInfo::exists(localPath)) { - // keep in sync with ActivityWidget::slotItemContextMenu - menu->addAction(tr("Show in file browser"), parent, [localPath] { - if (QFileInfo::exists(localPath)) { - showInFileManager(localPath); - } - }); - } + { + const QString localPath = data.folder()->path() + data.path(); + if (QFileInfo::exists(localPath)) { + // keep in sync with ActivityWidget::slotItemContextMenu + menu->addAction(tr("Show in file browser"), parent, [localPath] { + if (QFileInfo::exists(localPath)) { + showInFileManager(localPath); + } + }); } // "Open in Browser" action { - fetchPrivateLinkUrl(folder->accountState()->account(), folder->remotePathTrailingSlash() + data.path(), parent, [parent, menu = QPointer<QMenu>(menu)](const QString &url) { + fetchPrivateLinkUrl(data.folder()->accountState()->account(), data.folder()->remotePathTrailingSlash() + data.path(), parent, [parent, menu = QPointer<QMenu>(menu)](const QString &url) { // as fetchPrivateLinkUrl is async we need to check the menu still exists if (menu) { menu->addAction(tr("Show in web browser"), parent, [url, parent] { @@ -123,9 +123,9 @@ void ProtocolWidget::showContextMenu(QWidget *parent, ProtocolItemModel *model, case SyncFileItem::SoftError: Q_FALLTHROUGH(); case SyncFileItem::BlacklistedError: - menu->addAction(tr("Retry sync"), parent, [folder, &data] { - folder->journalDb()->wipeErrorBlacklistEntry(data.path()); - FolderMan::instance()->scheduleFolderNext(folder); + menu->addAction(tr("Retry sync"), parent, [&data] { + data.folder()->journalDb()->wipeErrorBlacklistEntry(data.path()); + FolderMan::instance()->scheduleFolderNext(data.folder()); }); default: break; diff --git a/src/gui/protocolwidget.ui b/src/gui/protocolwidget.ui index 7941d7418..cdd97d3d7 100644 --- a/src/gui/protocolwidget.ui +++ b/src/gui/protocolwidget.ui @@ -17,7 +17,7 @@ <item> <widget class="QLabel" name="_headerLabel"> <property name="text"> - <string>TextLabel</string> + <string>Local sync protocol</string> </property> <property name="textFormat"> <enum>Qt::PlainText</enum> diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index eb2c669bf..b27278825 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,6 @@ include(owncloud_add_test.cmake) -add_library(syncenginetestutils STATIC syncenginetestutils.cpp) +add_library(syncenginetestutils STATIC testutils/syncenginetestutils.cpp testutils/testutils.cpp) target_link_libraries(syncenginetestutils PUBLIC owncloudCore Qt5::Test) owncloud_add_test(OwncloudPropagator) diff --git a/test/benchmarks/benchlargesync.cpp b/test/benchmarks/benchlargesync.cpp index 9e78b9d5c..05b7c1b9d 100644 --- a/test/benchmarks/benchlargesync.cpp +++ b/test/benchmarks/benchlargesync.cpp @@ -5,7 +5,7 @@ * */ -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/modeltests/testactivitymodel.cpp b/test/modeltests/testactivitymodel.cpp index ef7899257..fa9b7d2d6 100644 --- a/test/modeltests/testactivitymodel.cpp +++ b/test/modeltests/testactivitymodel.cpp @@ -9,6 +9,8 @@ #include "gui/models/activitylistmodel.h" #include "gui/accountmanager.h" +#include "testutils/testutils.h" + #include <QTest> #include <QAbstractItemModelTester> @@ -25,19 +27,8 @@ private Q_SLOTS: new QAbstractItemModelTester(model, this); - auto manager = AccountManager::instance(); - - auto createAcc = [&] { - // don't use the account manager to create the account, it would try to use widgets - auto acc = Account::create(); - acc->setUrl(QUrl(QStringLiteral("http://admin:admin@localhost/owncloud"))); - acc->setDavDisplayName(QStringLiteral("fakename") + acc->uuid().toString()); - acc->setServerVersion(QStringLiteral("10.0.0")); - manager->addAccount(acc); - return acc; - }; - auto acc1 = createAcc(); - auto acc2 = createAcc(); + auto acc1 = TestUtils::createDummyAccount(); + auto acc2 = TestUtils::createDummyAccount(); model->setActivityList({ Activity { Activity::ActivityType, 1, acc1, "test", "test", "foo.cpp", QUrl::fromUserInput("https://owncloud.com"), QDateTime::currentDateTime() }, @@ -49,7 +40,7 @@ private Q_SLOTS: Activity { Activity::ActivityType, 2, acc1, "test", "test", "foo.cpp", QUrl::fromUserInput("https://owncloud.com"), QDateTime::currentDateTime() }, Activity { Activity::ActivityType, 4, acc2, "test", "test", "foo.cpp", QUrl::fromUserInput("https://owncloud.com"), QDateTime::currentDateTime() }, }); - model->slotRemoveAccount(manager->accounts().first().data()); + model->slotRemoveAccount(AccountManager::instance()->accounts().first().data()); } }; } diff --git a/test/modeltests/testprotocolmodel.cpp b/test/modeltests/testprotocolmodel.cpp index 8132f9f63..e2c194c2f 100644 --- a/test/modeltests/testprotocolmodel.cpp +++ b/test/modeltests/testprotocolmodel.cpp @@ -7,9 +7,15 @@ */ #include "gui/models/protocolitemmodel.h" +#include "gui/accountmanager.h" +#include "gui/accountstate.h" +#include "gui/folderman.h" + +#include "testutils/testutils.h" #include <QTest> #include <QAbstractItemModelTester> +#include <folder.h> namespace OCC { @@ -24,6 +30,20 @@ private Q_SLOTS: new QAbstractItemModelTester(model, this); + QTemporaryDir dir; + + auto account = TestUtils::createDummyAccount(); + + AccountStatePtr newAccountState(new AccountState(account)); + const QDir d(dir.path()); + QVERIFY(d.mkdir("foo")); + QVERIFY(d.mkdir("bar")); + const QString foo = dir.path() + QStringLiteral("/foo"); + const QString bar = dir.path() + QStringLiteral("/bar"); + QVERIFY(TestUtils::folderMan()->addFolder(newAccountState.data(), TestUtils::createDummyFolderDefinition(foo))); + QVERIFY(TestUtils::folderMan()->addFolder(newAccountState.data(), TestUtils::createDummyFolderDefinition(bar))); + + // populate with dummy data // -1 to test the ring buffer window roll over const auto size = model->rawData().capacity() - 1; @@ -31,13 +51,15 @@ private Q_SLOTS: std::vector<ProtocolItem> tmp; tmp.reserve(size); for (size_t i = 0; i < size; ++i) { - tmp.emplace_back(QStringLiteral("foo") + QString::number(i), item); + item->_file = QString::number(i); + tmp.emplace_back(foo, item); } model->reset(std::move(tmp)); // test some inserts for (int i = 0; i < 5; ++i) { - model->addProtocolItem(ProtocolItem { QStringLiteral("bar") + QString::number(i), item }); + item->_file = QString::number(i); + model->addProtocolItem(ProtocolItem { bar, item }); } const auto oldSize = model->rowCount(); @@ -45,8 +67,8 @@ private Q_SLOTS: // pick one from the middle const auto toBeRemoved = { model->protocolItem(model->index(0, 0)), - model->protocolItem(model->index(model->rawData().capacity() / 2, 0)), - model->protocolItem(model->index(model->rawData().capacity() / 3, 0)) + model->protocolItem(model->index(static_cast<int>(model->rawData().capacity()) / 2, 0)), + model->protocolItem(model->index(static_cast<int>(model->rawData().capacity()) / 3, 0)) }; std::vector<ProtocolItem> copy; @@ -58,7 +80,7 @@ private Q_SLOTS: int matches = 0; const auto filter = [&toBeRemoved, &matches](const ProtocolItem &pi) { for (const auto &tb : toBeRemoved) { - if (pi.folderName() == tb.folderName()) { + if (pi.folder() == tb.folder() && pi.path() == tb.path()) { matches++; return true; } @@ -74,7 +96,7 @@ private Q_SLOTS: // ensure we kept the original order for (int i = 0; i < model->rowCount(); ++i) { - QCOMPARE(model->protocolItem(model->index(i, 0)).folderName(), copy[i].folderName()); + QCOMPARE(model->protocolItem(model->index(i, 0)).folder(), copy[i].folder()); } } }; diff --git a/test/testallfilesdeleted.cpp b/test/testallfilesdeleted.cpp index e7b89cfec..e3ad69995 100644 --- a/test/testallfilesdeleted.cpp +++ b/test/testallfilesdeleted.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testblacklist.cpp b/test/testblacklist.cpp index d71326560..3a4fe93be 100644 --- a/test/testblacklist.cpp +++ b/test/testblacklist.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testchunkingng.cpp b/test/testchunkingng.cpp index 24e248d09..401a21c13 100644 --- a/test/testchunkingng.cpp +++ b/test/testchunkingng.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testcredentialmanager.cpp b/test/testcredentialmanager.cpp index f0ac646b2..9afea5ef0 100644 --- a/test/testcredentialmanager.cpp +++ b/test/testcredentialmanager.cpp @@ -7,7 +7,7 @@ #include "account.h" #include "libsync/creds/credentialmanager.h" -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <QTest> diff --git a/test/testdatabaseerror.cpp b/test/testdatabaseerror.cpp index 4c2ad5de2..bb19c6477 100644 --- a/test/testdatabaseerror.cpp +++ b/test/testdatabaseerror.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testdownload.cpp b/test/testdownload.cpp index ec451e07b..cd0635ad6 100644 --- a/test/testdownload.cpp +++ b/test/testdownload.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> #include <owncloudpropagator.h> diff --git a/test/testfolderman.cpp b/test/testfolderman.cpp index 6cbc0e03c..4e9437b09 100644 --- a/test/testfolderman.cpp +++ b/test/testfolderman.cpp @@ -14,36 +14,15 @@ #include "account.h" #include "accountstate.h" #include "configfile.h" -#include "creds/httpcredentials.h" -using namespace OCC; - -class HttpCredentialsTest : public HttpCredentials { -public: - HttpCredentialsTest(const QString& user, const QString& password) - : HttpCredentials(DetermineAuthTypeJob::AuthType::Basic, user, password) - {} - - void askFromUser() override { - - } -}; +#include "testutils/testutils.h" -static FolderDefinition folderDefinition(const QString &path) { - FolderDefinition d; - d.localPath = path; - d.targetPath = path; - d.alias = path; - return d; -} +using namespace OCC; class TestFolderMan: public QObject { Q_OBJECT - - FolderMan _fm; - private slots: void testCheckPathValidityForNewFolder() { @@ -64,17 +43,12 @@ private slots: } QString dirPath = dir2.canonicalPath(); - AccountPtr account = Account::create(); - QUrl url("http://example.de"); - HttpCredentialsTest *cred = new HttpCredentialsTest("testuser", "secret"); - account->setCredentials(cred); - account->setUrl( url ); - + AccountPtr account = TestUtils::createDummyAccount(); AccountStatePtr newAccountState(new AccountState(account)); - FolderMan *folderman = FolderMan::instance(); - QCOMPARE(folderman, &_fm); - QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/sub/ownCloud1"))); - QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/ownCloud2"))); + FolderMan *folderman = TestUtils::folderMan(); + QCOMPARE(folderman, FolderMan::instance()); + QVERIFY(folderman->addFolder(newAccountState.data(), TestUtils::createDummyFolderDefinition(dirPath + "/sub/ownCloud1"))); + QVERIFY(folderman->addFolder(newAccountState.data(), TestUtils::createDummyFolderDefinition(dirPath + "/ownCloud2"))); // those should be allowed @@ -91,7 +65,7 @@ private slots: QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + "/sub/file.txt").isNull()); // There are folders configured in those folders, url needs to be taken into account: -> ERROR - QUrl url2(url); + QUrl url2(account->url()); const QString user = account->credentials()->user(); url2.setUserName(user); @@ -174,7 +148,6 @@ private slots: // SETUP QTemporaryDir dir; - ConfigFile::setConfDir(dir.path()); // we don't want to pollute the user's config file QVERIFY(dir.isValid()); QDir dir2(dir.path()); QVERIFY(dir2.mkpath("sub/ownCloud1/folder/f")); @@ -185,18 +158,14 @@ private slots: QVERIFY(dir2.mkpath("free2/sub")); QString dirPath = dir2.canonicalPath(); - AccountPtr account = Account::create(); - QUrl url("http://example.de"); - HttpCredentialsTest *cred = new HttpCredentialsTest("testuser", "secret"); - account->setCredentials(cred); - account->setUrl( url ); - url.setUserName(cred->user()); + AccountPtr account = TestUtils::createDummyAccount(); + QUrl url(account->url()); + url.setUserName(account->credentials()->user()); AccountStatePtr newAccountState(new AccountState(account)); - FolderMan *folderman = FolderMan::instance(); - QCOMPARE(folderman, &_fm); - QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/sub/ownCloud/"))); - QVERIFY(folderman->addFolder(newAccountState.data(), folderDefinition(dirPath + "/ownCloud2/"))); + FolderMan *folderman = TestUtils::folderMan(); + QVERIFY(folderman->addFolder(newAccountState.data(), TestUtils::createDummyFolderDefinition(dirPath + "/sub/ownCloud/"))); + QVERIFY(folderman->addFolder(newAccountState.data(), TestUtils::createDummyFolderDefinition(dirPath + "/ownCloud2/"))); // TEST diff --git a/test/testjobqueue.cpp b/test/testjobqueue.cpp index aeb2063cb..7fca54082 100644 --- a/test/testjobqueue.cpp +++ b/test/testjobqueue.cpp @@ -9,7 +9,7 @@ #include "abstractnetworkjob.h" #include "account.h" -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <QTest> diff --git a/test/testlocaldiscovery.cpp b/test/testlocaldiscovery.cpp index 18e1c1b9d..643a3c96a 100644 --- a/test/testlocaldiscovery.cpp +++ b/test/testlocaldiscovery.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> #include <localdiscoverytracker.h> diff --git a/test/testlockedfiles.cpp b/test/testlockedfiles.cpp index 2ffedb8e3..a96dbea64 100644 --- a/test/testlockedfiles.cpp +++ b/test/testlockedfiles.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include "lockwatcher.h" #include <syncengine.h> #include <localdiscoverytracker.h> diff --git a/test/testoauth.cpp b/test/testoauth.cpp index 42de3a3cf..a8b0dbaaf 100644 --- a/test/testoauth.cpp +++ b/test/testoauth.cpp @@ -9,7 +9,7 @@ #include <QDesktopServices> #include "libsync/creds/oauth.h" -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include "theme.h" #include "common/asserts.h" diff --git a/test/testpermissions.cpp b/test/testpermissions.cpp index 6836c331f..012c91a71 100644 --- a/test/testpermissions.cpp +++ b/test/testpermissions.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> #include "common/ownsql.h" diff --git a/test/testremotediscovery.cpp b/test/testremotediscovery.cpp index a93c16039..b6b696bb3 100644 --- a/test/testremotediscovery.cpp +++ b/test/testremotediscovery.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> #include <localdiscoverytracker.h> diff --git a/test/testselectivesync.cpp b/test/testselectivesync.cpp index c91bd8b76..67f44d3fc 100644 --- a/test/testselectivesync.cpp +++ b/test/testselectivesync.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testsyncconflict.cpp b/test/testsyncconflict.cpp index 1a1becdc9..dde1eb751 100644 --- a/test/testsyncconflict.cpp +++ b/test/testsyncconflict.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testsyncdelete.cpp b/test/testsyncdelete.cpp index c2633ba4b..780b5e684 100644 --- a/test/testsyncdelete.cpp +++ b/test/testsyncdelete.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index 1ee5bdb84..89fe33420 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testsyncfilestatustracker.cpp b/test/testsyncfilestatustracker.cpp index f1b27447c..823910514 100644 --- a/test/testsyncfilestatustracker.cpp +++ b/test/testsyncfilestatustracker.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include "csync_exclude.h" using namespace OCC; diff --git a/test/testsyncmove.cpp b/test/testsyncmove.cpp index 8e09ba693..047e5149b 100644 --- a/test/testsyncmove.cpp +++ b/test/testsyncmove.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> using namespace OCC; diff --git a/test/testsyncvirtualfiles.cpp b/test/testsyncvirtualfiles.cpp index f46888518..ffcf1c1fa 100644 --- a/test/testsyncvirtualfiles.cpp +++ b/test/testsyncvirtualfiles.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include "common/vfs.h" #include "config.h" #include <syncengine.h> diff --git a/test/testuploadreset.cpp b/test/testuploadreset.cpp index cc7d4c5ae..d954e7553 100644 --- a/test/testuploadreset.cpp +++ b/test/testuploadreset.cpp @@ -6,7 +6,7 @@ */ #include <QtTest> -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include <syncengine.h> #include <common/syncjournaldb.h> diff --git a/test/syncenginetestutils.cpp b/test/testutils/syncenginetestutils.cpp index a4b1a1c37..c3422b131 100644 --- a/test/syncenginetestutils.cpp +++ b/test/testutils/syncenginetestutils.cpp @@ -5,7 +5,7 @@ * */ -#include "syncenginetestutils.h" +#include "testutils/syncenginetestutils.h" #include "httplogger.h" #include "accessmanager.h" #include "libsync/configfile.h" @@ -346,7 +346,8 @@ FakePropfindReply::FakePropfindReply(FileInfo &remoteRootFileInfo, QNetworkAcces xml.writeTextElement(davUri, QStringLiteral("getlastmodified"), stringDate); xml.writeTextElement(davUri, QStringLiteral("getcontentlength"), QString::number(fileInfo.size)); xml.writeTextElement(davUri, QStringLiteral("getetag"), QStringLiteral("\"%1\"").arg(QString::fromLatin1(fileInfo.etag))); - xml.writeTextElement(ocUri, QStringLiteral("permissions"), !fileInfo.permissions.isNull() ? QString(fileInfo.permissions.toString()) : fileInfo.isShared ? QStringLiteral("SRDNVCKW") : QStringLiteral("RDNVCKW")); + xml.writeTextElement(ocUri, QStringLiteral("permissions"), !fileInfo.permissions.isNull() ? QString(fileInfo.permissions.toString()) : fileInfo.isShared ? QStringLiteral("SRDNVCKW") + : QStringLiteral("RDNVCKW")); xml.writeTextElement(ocUri, QStringLiteral("id"), QString::fromUtf8(fileInfo.fileId)); xml.writeTextElement(ocUri, QStringLiteral("checksums"), QString::fromUtf8(fileInfo.checksums)); buffer.write(fileInfo.extraDavProperties); diff --git a/test/syncenginetestutils.h b/test/testutils/syncenginetestutils.h index 72ef5d91a..98c0759ec 100644 --- a/test/syncenginetestutils.h +++ b/test/testutils/syncenginetestutils.h @@ -10,6 +10,7 @@ #include "creds/abstractcredentials.h" #include "logger.h" #include "filesystem.h" +#include "folder.h" #include "syncengine.h" #include "common/syncjournaldb.h" #include "common/syncjournalfilerecord.h" @@ -34,7 +35,8 @@ static const QUrl sRootUrl = QUrl::fromEncoded("owncloud://somehost/owncloud/rem static const QUrl sRootUrl2 = QUrl::fromEncoded("owncloud://somehost/owncloud/remote.php/dav/files/admin/"); static const QUrl sUploadUrl = QUrl::fromEncoded("owncloud://somehost/owncloud/remote.php/dav/uploads/admin/"); -inline QString getFilePathFromUrl(const QUrl &url) { +inline QString getFilePathFromUrl(const QUrl &url) +{ QString path = url.path(); if (path.startsWith(sRootUrl.path())) return path.mid(sRootUrl.path().length()); @@ -46,14 +48,17 @@ inline QString getFilePathFromUrl(const QUrl &url) { } -inline QByteArray generateEtag() { +inline QByteArray generateEtag() +{ return QByteArray::number(QDateTime::currentDateTimeUtc().toMSecsSinceEpoch(), 16) + QByteArray::number(qrand(), 16); } -inline QByteArray generateFileId() { +inline QByteArray generateFileId() +{ return QByteArray::number(qrand(), 16); } -class PathComponents : public QStringList { +class PathComponents : public QStringList +{ public: PathComponents(const char *path); PathComponents(const QString &path); @@ -61,7 +66,11 @@ public: PathComponents parentDirComponents() const; PathComponents subComponents() const &; - PathComponents subComponents() && { removeFirst(); return std::move(*this); } + PathComponents subComponents() && + { + removeFirst(); + return std::move(*this); + } QString pathRoot() const { return first(); } QString fileName() const { return last(); } }; @@ -83,8 +92,12 @@ public: class DiskFileModifier : public FileModifier { QDir _rootDir; + public: - DiskFileModifier(const QString &rootDirPath) : _rootDir(rootDirPath) { } + DiskFileModifier(const QString &rootDirPath) + : _rootDir(rootDirPath) + { + } void remove(const QString &relativePath) override; void insert(const QString &relativePath, qint64 size = 64, char contentChar = 'W') override; void setContents(const QString &relativePath, char contentChar) override; @@ -102,9 +115,23 @@ public: static FileInfo A12_B12_C12_S12(); FileInfo() = default; - FileInfo(const QString &name) : name{name} { } - FileInfo(const QString &name, qint64 size) : name{name}, isDir{false}, size{size} { } - FileInfo(const QString &name, qint64 size, char contentChar) : name{name}, isDir{false}, size{size}, contentChar{contentChar} { } + FileInfo(const QString &name) + : name { name } + { + } + FileInfo(const QString &name, qint64 size) + : name { name } + , isDir { false } + , size { size } + { + } + FileInfo(const QString &name, qint64 size, char contentChar) + : name { name } + , isDir { false } + , size { size } + , contentChar { contentChar } + { + } FileInfo(const QString &name, const std::initializer_list<FileInfo> &children); void addChild(const FileInfo &info); @@ -131,13 +158,15 @@ public: FileInfo *create(const QString &relativePath, qint64 size, char contentChar); - bool operator<(const FileInfo &other) const { + bool operator<(const FileInfo &other) const + { return name < other.name; } bool operator==(const FileInfo &other) const; - bool operator!=(const FileInfo &other) const { + bool operator!=(const FileInfo &other) const + { return !operator==(other); } @@ -164,7 +193,8 @@ public: FileInfo *findInvalidatingEtags(PathComponents pathComponents); - friend inline QDebug operator<<(QDebug dbg, const FileInfo& fi) { + friend inline QDebug operator<<(QDebug dbg, const FileInfo &fi) + { return dbg << "{ " << fi.path() << ": " << fi.children; } }; @@ -202,6 +232,7 @@ class FakePutReply : public FakeReply { Q_OBJECT FileInfo *fileInfo; + public: FakePutReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, const QByteArray &putPayload, QObject *parent); @@ -217,6 +248,7 @@ class FakeMkcolReply : public FakeReply { Q_OBJECT FileInfo *fileInfo; + public: FakeMkcolReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, QObject *parent); @@ -292,6 +324,7 @@ class FakeChunkMoveReply : public FakeReply { Q_OBJECT FileInfo *fileInfo; + public: FakeChunkMoveReply(FileInfo &uploadsFileInfo, FileInfo &remoteRootFileInfo, QNetworkAccessManager::Operation op, const QNetworkRequest &request, @@ -317,7 +350,7 @@ public: void respond(); - void abort() override {} + void abort() override { } qint64 readData(char *buf, qint64 max) override; qint64 bytesAvailable() const override; QByteArray _body; @@ -334,8 +367,8 @@ public: Q_INVOKABLE virtual void respond(); // make public to give tests easy interface - using QNetworkReply::setError; using QNetworkReply::setAttribute; + using QNetworkReply::setError; public slots: void slotSetFinished(); @@ -365,7 +398,7 @@ class DelayedReply : public OriginalReply { public: template <typename... Args> - explicit DelayedReply(quint64 delayMS, Args &&... args) + explicit DelayedReply(quint64 delayMS, Args &&...args) : OriginalReply(std::forward<Args>(args)...) , _delayMs(delayMS) { @@ -411,8 +444,12 @@ protected: class FakeCredentials : public OCC::AbstractCredentials { QNetworkAccessManager *_qnam; + public: - FakeCredentials(QNetworkAccessManager *qnam) : _qnam{qnam} { } + FakeCredentials(QNetworkAccessManager *qnam) + : _qnam { qnam } + { + } QString authType() const override { return QStringLiteral("test"); } QString user() const override { return QStringLiteral("admin"); } QNetworkAccessManager *createQNAM() const override { return _qnam; } @@ -452,13 +489,16 @@ public: FileInfo &uploadState() { return _fakeQnam->uploadState(); } FileInfo dbState() const; - struct ErrorList { + struct ErrorList + { FakeQNAM *_qnam; void append(const QString &path, int error = 500) - { _qnam->errorPaths().insert(path, error); } + { + _qnam->errorPaths().insert(path, error); + } void clear() { _qnam->errorPaths().clear(); } }; - ErrorList serverErrorPaths() { return {_fakeQnam}; } + ErrorList serverErrorPaths() { return { _fakeQnam }; } void setServerOverride(const FakeQNAM::Override &override) { _fakeQnam->setOverride(override); } QString localPath() const; @@ -469,14 +509,16 @@ public: void execUntilItemCompleted(const QString &relativePath); - bool execUntilFinished() { + bool execUntilFinished() + { QSignalSpy spy(_syncEngine.get(), SIGNAL(finished(bool))); bool ok = spy.wait(3600000); Q_ASSERT(ok && "Sync timed out"); return spy[0][0].toBool(); } - bool syncOnce() { + bool syncOnce() + { scheduleSync(); return execUntilFinished(); } @@ -504,19 +546,22 @@ inline const FileInfo *findConflict(FileInfo &dir, const QString &filename) return nullptr; } -struct ItemCompletedSpy : QSignalSpy { +struct ItemCompletedSpy : QSignalSpy +{ explicit ItemCompletedSpy(FakeFolder &folder) : QSignalSpy(&folder.syncEngine(), &OCC::SyncEngine::itemCompleted) - {} + { + } OCC::SyncFileItemPtr findItem(const QString &path) const; }; // QTest::toString overloads namespace OCC { - inline char *toString(const SyncFileStatus &s) { - return QTest::toString(QStringLiteral("SyncFileStatus(%1)").arg(s.toSocketAPIString())); - } +inline char *toString(const SyncFileStatus &s) +{ + return QTest::toString(QStringLiteral("SyncFileStatus(%1)").arg(s.toSocketAPIString())); +} } inline void addFiles(QStringList &dest, const FileInfo &fi) @@ -548,20 +593,11 @@ inline void addFilesDbData(QStringList &dest, const FileInfo &fi) { // could include etag, permissions etc, but would need extra work if (fi.isDir) { - dest += QStringLiteral("%1 - %2 %3 %4").arg( - fi.name, - fi.isDir ? QStringLiteral("dir") : QStringLiteral("file"), - QString::number(fi.lastModified.toSecsSinceEpoch()), - QString::fromUtf8(fi.fileId)); + dest += QStringLiteral("%1 - %2 %3 %4").arg(fi.name, fi.isDir ? QStringLiteral("dir") : QStringLiteral("file"), QString::number(fi.lastModified.toSecsSinceEpoch()), QString::fromUtf8(fi.fileId)); for (const auto &fi : fi.children) addFilesDbData(dest, fi); } else { - dest += QStringLiteral("%1 - %2 %3 %4 %5").arg( - fi.name, - fi.isDir ? QStringLiteral("dir") : QStringLiteral("file"), - QString::number(fi.size), - QString::number(fi.lastModified.toSecsSinceEpoch()), - QString::fromUtf8(fi.fileId)); + dest += QStringLiteral("%1 - %2 %3 %4 %5").arg(fi.name, fi.isDir ? QStringLiteral("dir") : QStringLiteral("file"), QString::number(fi.size), QString::number(fi.lastModified.toSecsSinceEpoch()), QString::fromUtf8(fi.fileId)); } } diff --git a/test/testutils/testutils.cpp b/test/testutils/testutils.cpp new file mode 100644 index 000000000..281323073 --- /dev/null +++ b/test/testutils/testutils.cpp @@ -0,0 +1,59 @@ +#include "testutils.h" + +#include "creds/httpcredentials.h" +#include "gui/accountmanager.h" + +#include <QCoreApplication> + +namespace { +class HttpCredentialsTest : public OCC::HttpCredentials +{ +public: + HttpCredentialsTest(const QString &user, const QString &password) + : HttpCredentials(OCC::DetermineAuthTypeJob::AuthType::Basic, user, password) + { + } + + void askFromUser() override + { + } +}; +} + +namespace OCC { + +namespace TestUtils { + AccountPtr createDummyAccount() + { + // don't use the account manager to create the account, it would try to use widgets + auto acc = Account::create(); + HttpCredentialsTest *cred = new HttpCredentialsTest("testuser", "secret"); + acc->setCredentials(cred); + acc->setUrl(QUrl(QStringLiteral("http://localhost/owncloud"))); + acc->setDavDisplayName(QStringLiteral("fakename") + acc->uuid().toString()); + acc->setServerVersion(QStringLiteral("10.0.0")); + OCC::AccountManager::instance()->addAccount(acc); + return acc; + } + + FolderDefinition createDummyFolderDefinition(const QString &path) + { + OCC::FolderDefinition d; + d.localPath = path; + d.targetPath = path; + d.alias = path; + return d; + } + + FolderMan *folderMan() + { + static FolderMan *man = [] { + auto man = new FolderMan; + QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, man, &FolderMan::deleteLater); + return man; + }(); + return man; + } + +} +} diff --git a/test/testutils/testutils.h b/test/testutils/testutils.h new file mode 100644 index 000000000..c9e8c64e5 --- /dev/null +++ b/test/testutils/testutils.h @@ -0,0 +1,14 @@ +#pragma once + +#include "account.h" +#include "folder.h" +#include "folderman.h" + +namespace OCC { + +namespace TestUtils { + FolderMan *folderMan(); + FolderDefinition createDummyFolderDefinition(const QString &path); + AccountPtr createDummyAccount(); +} +} |