Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/desktop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Cambra <claudio.cambra@nextcloud.com>2022-10-18 18:15:10 +0300
committerClaudio Cambra <claudio.cambra@nextcloud.com>2022-10-31 20:06:10 +0300
commit7ba6969e65b4491e3ba7f866a3ddd3e0556b1fc9 (patch)
treeb01ab44d37ac17cd4678444bc0d2f10a8f7eeca3
parenta0ff46a7fbb94ed4a815244f14a7ef1caa9f1d97 (diff)
Moved all server mocking code for share model test to independent ShareTestUtils file
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
-rw-r--r--src/gui/folderman.h3
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/sharetestutils.cpp442
-rw-r--r--test/sharetestutils.h136
-rw-r--r--test/testhelper.cpp18
-rw-r--r--test/testhelper.h2
-rw-r--r--test/testsharemodel.cpp920
7 files changed, 801 insertions, 721 deletions
diff --git a/src/gui/folderman.h b/src/gui/folderman.h
index 8cc499cd8..6409cc8b4 100644
--- a/src/gui/folderman.h
+++ b/src/gui/folderman.h
@@ -28,6 +28,7 @@
class TestFolderMan;
class TestCfApiShellExtensionsIPC;
class TestShareModel;
+class ShareTestHelper;
namespace OCC {
@@ -380,7 +381,7 @@ private:
friend class OCC::Application;
friend class ::TestFolderMan;
friend class ::TestCfApiShellExtensionsIPC;
- friend class ::TestShareModel;
+ friend class ::ShareTestHelper;
};
} // namespace OCC
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 820984631..d3cd1f93a 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -10,6 +10,7 @@ add_library(testutils
pushnotificationstestutils.cpp
themeutils.cpp
testhelper.cpp
+ sharetestutils.cpp
)
target_link_libraries(testutils PUBLIC Nextcloud::sync Qt5::Test)
diff --git a/test/sharetestutils.cpp b/test/sharetestutils.cpp
new file mode 100644
index 000000000..7f481a612
--- /dev/null
+++ b/test/sharetestutils.cpp
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
+ *
+ * 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.
+ */
+
+#include "sharetestutils.h"
+
+#include "testhelper.h"
+
+using namespace OCC;
+
+FakeShareDefinition::FakeShareDefinition(ShareTestHelper *helper,
+ const Share::ShareType type,
+ const QString &shareWith,
+ const QString &displayString,
+ const QString &password,
+ const QString &note,
+ const QString &expiration)
+{
+ ++helper->latestShareId;
+ const auto idString = QString::number(helper->latestShareId);
+
+
+ fileDefinition = helper->fakeFileDefinition;
+ shareId = idString;
+ shareCanDelete = true;
+ shareCanEdit = true;
+ shareUidOwner = helper->account->davUser();;
+ shareDisplayNameOwner = helper->account->davDisplayName();
+ sharePassword = password;
+ sharePermissions = static_cast<int>(SharePermissions(SharePermissionRead |
+ SharePermissionUpdate |
+ SharePermissionCreate |
+ SharePermissionDelete |
+ SharePermissionShare));
+ shareNote = note;
+ shareHideDownload = 0;
+ shareExpiration = expiration;
+ shareSendPasswordByTalk = false;
+ shareType = type;
+
+ const auto token = QString(QStringLiteral("GQ4aLrZEdJJkopW-") + idString);
+ // Weird, but it's what the server does
+ const auto finalShareWith = type == Share::TypeLink ? password : shareWith;
+ const auto shareWithDisplayName = type == Share::TypeLink ? QStringLiteral("(Shared Link)") : displayString;
+ const auto linkLabel = type == Share::TypeLink ? displayString : QString();
+ const auto linkName = linkShareLabel;
+ const auto linkUrl = type == Share::TypeLink ? QString(helper->account->davUrl().toString() + QStringLiteral("/s/") + token) : QString();
+
+ shareShareWith = finalShareWith;
+ shareShareWithDisplayName = shareWithDisplayName;
+ shareToken = token;
+ linkShareName = linkName;
+ linkShareLabel = linkLabel;
+ linkShareUrl = linkUrl;
+}
+
+QJsonObject FakeShareDefinition::toShareJsonObject() const
+{
+ QJsonObject newShareJson;
+ newShareJson.insert("uid_file_owner", fileDefinition.fileOwnerUid);
+ newShareJson.insert("displayname_file_owner", fileDefinition.fileOwnerDisplayName);
+ newShareJson.insert("file_target", fileDefinition.fileTarget);
+ newShareJson.insert("has_preview", fileDefinition.fileHasPreview);
+ newShareJson.insert("file_parent", fileDefinition.fileFileParent);
+ newShareJson.insert("file_source", fileDefinition.fileSource);
+ newShareJson.insert("item_source", fileDefinition.fileItemSource);
+ newShareJson.insert("item_type", fileDefinition.fileItemType);
+ newShareJson.insert("mail_send", fileDefinition.fileMailSend);
+ newShareJson.insert("mimetype", fileDefinition.fileMimeType);
+ newShareJson.insert("parent", fileDefinition.fileParent);
+ newShareJson.insert("path", fileDefinition.filePath);
+ newShareJson.insert("storage", fileDefinition.fileStorage);
+ newShareJson.insert("storage_id", fileDefinition.fileStorageId);
+ newShareJson.insert("id", shareId);
+ newShareJson.insert("can_delete", shareCanDelete);
+ newShareJson.insert("can_edit", shareCanEdit);
+ newShareJson.insert("uid_owner", shareUidOwner);
+ newShareJson.insert("displayname_owner", shareDisplayNameOwner);
+ newShareJson.insert("password", sharePassword);
+ newShareJson.insert("permissions", sharePermissions);
+ newShareJson.insert("note", shareNote);
+ newShareJson.insert("hide_download", shareHideDownload);
+ newShareJson.insert("expiration", shareExpiration);
+ newShareJson.insert("send_password_by_talk", shareSendPasswordByTalk);
+ newShareJson.insert("share_type", shareType);
+ newShareJson.insert("share_with", shareShareWith);
+ newShareJson.insert("share_with_displayname", shareShareWithDisplayName);
+ newShareJson.insert("token", shareToken);
+ newShareJson.insert("name", linkShareName);
+ newShareJson.insert("label", linkShareLabel);
+ newShareJson.insert("url", linkShareUrl);
+
+ return newShareJson;
+}
+
+QByteArray FakeShareDefinition::toRequestReply() const
+{
+ const auto shareJson = toShareJsonObject();
+ return jsonValueToOccReply(shareJson);
+}
+
+// Below is ShareTestHelper
+ShareTestHelper::ShareTestHelper(QObject *parent)
+ : QObject(parent)
+{
+}
+
+ShareTestHelper::~ShareTestHelper()
+{
+ const auto folder = FolderMan::instance()->folder(fakeFolder.localPath());
+ if (folder) {
+ FolderMan::instance()->removeFolder(folder);
+ }
+ AccountManager::instance()->deleteAccount(accountState.data());
+}
+
+void ShareTestHelper::setup()
+{
+ _fakeQnam.reset(new FakeQNAM({}));
+ _fakeQnam->setOverride([this](const QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device) {
+ return qnamOverride(op, req, device);
+ });
+
+ account = Account::create();
+ account->setCredentials(new FakeCredentials{_fakeQnam.data()});
+ account->setUrl(QUrl(("owncloud://somehost/owncloud")));
+ account->setCapabilities(_fakeCapabilities);
+ accountState = new AccountState(account);
+ AccountManager::instance()->addAccount(account);
+
+ QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+ fakeFolder.localModifier().insert(testFileName);
+
+ const auto folderMan = FolderMan::instance();
+ QCOMPARE(folderMan, &fm);
+ QVERIFY(folderMan->addFolder(accountState.data(), folderDefinition(fakeFolder.localPath())));
+ const auto folder = FolderMan::instance()->folder(fakeFolder.localPath());
+ QVERIFY(folder);
+ QVERIFY(fakeFolder.syncOnce());
+ QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+
+ const auto fakeFileInfo = fakeFolder.remoteModifier().find(testFileName);
+ QVERIFY(fakeFileInfo);
+ fakeFileInfo->permissions.setPermission(RemotePermissions::CanReshare);
+ QVERIFY(fakeFolder.syncOnce());
+ QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
+ QVERIFY(fakeFileInfo->permissions.CanReshare);
+
+ _fakeCapabilities = QVariantMap {
+ {QStringLiteral("files_sharing"), QVariantMap {
+ {QStringLiteral("api_enabled"), true},
+ {QStringLiteral("default_permissions"), 19},
+ {QStringLiteral("public"), QVariantMap {
+ {QStringLiteral("enabled"), true},
+ {QStringLiteral("expire_date"), QVariantMap {
+ {QStringLiteral("days"), 30},
+ {QStringLiteral("enforced"), false},
+ }},
+ {QStringLiteral("expire_date_internal"), QVariantMap {
+ {QStringLiteral("days"), 30},
+ {QStringLiteral("enforced"), false},
+ }},
+ {QStringLiteral("expire_date_remote"), QVariantMap {
+ {QStringLiteral("days"), 30},
+ {QStringLiteral("enforced"), false},
+ }},
+ {QStringLiteral("password"), QVariantMap {
+ {QStringLiteral("enforced"), false},
+ }},
+ }},
+ {QStringLiteral("sharebymail"), QVariantMap {
+ {QStringLiteral("enabled"), true},
+ {QStringLiteral("password"), QVariantMap {
+ {QStringLiteral("enforced"), false},
+ }},
+ }},
+ }},
+ };
+
+ // Generate test data
+ // Properties that apply to the file generally
+ const auto fileOwnerUid = account->davUser();
+ const auto fileOwnerDisplayName = account->davDisplayName();
+ const auto fileTarget = QString(QStringLiteral("/") + fakeFileInfo->name);
+ const auto fileHasPreview = true;
+ const auto fileFileParent = QString(fakeFolder.remoteModifier().fileId);
+ const auto fileSource = QString(fakeFileInfo->fileId);
+ const auto fileItemSource = fileSource;
+ const auto fileItemType = QStringLiteral("file");
+ const auto fileMailSend = 0;
+ const auto fileMimeType = QStringLiteral("text/markdown");
+ const auto fileParent = QString();
+ const auto filePath = fakeFileInfo->path();
+ const auto fileStorage = 3;
+ const auto fileStorageId = QString(QStringLiteral("home::") + account->davUser());
+
+ fakeFileDefinition = FakeFileReplyDefinition {
+ fileOwnerUid,
+ fileOwnerDisplayName,
+ fileTarget,
+ fileHasPreview,
+ fileFileParent,
+ fileSource,
+ fileItemSource,
+ fileItemType,
+ fileMailSend,
+ fileMimeType,
+ fileParent,
+ filePath,
+ fileStorage,
+ fileStorageId,
+ };
+
+ emit setupSucceeded();
+}
+
+QNetworkReply *ShareTestHelper::qnamOverride(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device)
+{
+ QNetworkReply *reply = nullptr;
+
+ const auto reqUrl = req.url();
+ const auto reqRawPath = reqUrl.path();
+ const auto reqPath = reqRawPath.startsWith("/owncloud/") ? reqRawPath.mid(10) : reqRawPath;
+ qDebug() << req.url() << reqPath << op;
+
+ // Properly formatted PROPFIND URL goes something like:
+ // https://cloud.nextcloud.com/remote.php/dav/files/claudio/Readme.md
+ if(reqPath.endsWith(testFileName) && req.attribute(QNetworkRequest::CustomVerbAttribute) == "PROPFIND") {
+
+ reply = new FakePropfindReply(fakeFolder.remoteModifier(), op, req, this);
+
+ } else if (req.url().toString().startsWith(accountState->account()->url().toString()) &&
+ reqPath.startsWith(QStringLiteral("ocs/v2.php/apps/files_sharing/api/v1/shares"))) {
+
+ if (op == QNetworkAccessManager::PostOperation) {
+ reply = handleSharePostOperation(op, req, device);
+
+ } else if(req.attribute(QNetworkRequest::CustomVerbAttribute) == "DELETE") {
+ reply = handleShareDeleteOperation(op, req, reqPath);
+
+ } else if(op == QNetworkAccessManager::PutOperation) {
+ reply = handleSharePutOperation(op, req, reqPath, device);
+
+ } else if(req.attribute(QNetworkRequest::CustomVerbAttribute) == "GET") {
+ reply = handleShareGetOperation(op, req, reqPath);
+ }
+ } else {
+ reply = new FakeErrorReply(op, req, this, 404, _fake404Response);
+ }
+
+ return reply;
+}
+
+QNetworkReply *ShareTestHelper::handleSharePostOperation(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device)
+{
+ QNetworkReply *reply = nullptr;
+
+ // POST https://somehost/owncloud/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json
+ // Header: { Ocs-APIREQUEST: true, Content-Type: application/x-www-form-urlencoded, X-Request-ID: 1527752d-e147-4da7-89b8-fb06315a5fad, }
+ // Data: [path=file.md&shareType=3]"
+ const QUrlQuery urlQuery(req.url());
+ const auto formatParam = urlQuery.queryItemValue(QStringLiteral("format"));
+
+ if (formatParam == QStringLiteral("json")) {
+ device->open(QIODevice::ReadOnly);
+ const auto requestBody = device->readAll();
+ device->close();
+
+ const auto requestData = requestBody.split('&');
+ // We don't care about path since we know the file we are testing with
+ auto requestShareType = -10; // Just in case
+ QString requestShareWith;
+ QString requestName;
+ QString requestPassword;
+
+ for(const auto &data : requestData) {
+ const auto requestDataUrl = QUrl::fromPercentEncoding(data);
+ const QString requestDataUrlString(requestDataUrl);
+
+ if (data.contains("shareType=")) {
+ const auto shareTypeString = requestDataUrlString.mid(10);
+ requestShareType = Share::ShareType(shareTypeString.toInt());
+ } else if (data.contains("shareWith=")) {
+ requestShareWith = data.mid(10);
+ } else if (data.contains("name=")) {
+ requestName = data.mid(5);
+ } else if (data.contains("password=")) {
+ requestPassword = data.mid(9);
+ }
+ }
+
+ if (requestPassword.isEmpty() &&
+ ((requestShareType == Share::TypeEmail && account->capabilities().shareEmailPasswordEnforced()) ||
+ (requestShareType == Share::TypeLink && account->capabilities().sharePublicLinkEnforcePassword()))) {
+
+ reply = new FakePayloadReply(op, req, _fake403Response, searchResultsReplyDelay, _fakeQnam.data());
+
+ } else if (requestShareType >= 0) {
+ const auto shareType = Share::ShareType(requestShareType);
+ reply = new FakePayloadReply(op, req, createNewShare(shareType, requestShareWith, requestPassword), searchResultsReplyDelay, _fakeQnam.data());
+ }
+ }
+
+ return reply;
+}
+
+QNetworkReply *ShareTestHelper::handleSharePutOperation(const QNetworkAccessManager::Operation op, const QNetworkRequest &req, const QString &reqPath, QIODevice *device)
+{
+ QNetworkReply *reply = nullptr;
+
+ const auto splitUrlPath = reqPath.split('/');
+ const auto shareId = splitUrlPath.last();
+
+ const QUrlQuery urlQuery(req.url());
+ const auto formatParam = urlQuery.queryItemValue(QStringLiteral("format"));
+
+ if (formatParam == QStringLiteral("json")) {
+ device->open(QIODevice::ReadOnly);
+ const auto requestBody = device->readAll();
+ device->close();
+
+ const auto requestData = requestBody.split('&');
+
+ const auto existingShareIterator = std::find_if(_sharesReplyData.cbegin(), _sharesReplyData.cend(), [&shareId](const QJsonValue &value) {
+ return value.toObject().value("id").toString() == shareId;
+ });
+
+ if (existingShareIterator == _sharesReplyData.cend()) {
+ reply = new FakeErrorReply(op, req, this, 404, _fake404Response);
+ } else {
+ const auto existingShareValue = *existingShareIterator;
+ auto shareObject = existingShareValue.toObject();
+
+ for (const auto &requestDataItem : requestData) {
+ const auto requestSplit = requestDataItem.split('=');
+ auto requestKey = requestSplit.first();
+ auto requestValue = requestSplit.last();
+
+ // We send expireDate without time but the server returns with time at 00:00:00
+ if (requestKey == "expireDate") {
+ requestKey = "expiration";
+ requestValue.append(" 00:00:00");
+ }
+
+ shareObject.insert(QString(requestKey), QString(requestValue));
+ }
+
+ _sharesReplyData.replace(existingShareIterator - _sharesReplyData.cbegin(), shareObject);
+ reply = new FakePayloadReply(op, req, jsonValueToOccReply(shareObject), searchResultsReplyDelay, _fakeQnam.data());
+ }
+ }
+
+ return reply;
+}
+
+
+QNetworkReply *ShareTestHelper::handleShareDeleteOperation(const QNetworkAccessManager::Operation op, const QNetworkRequest &req, const QString &reqPath)
+{
+ QNetworkReply *reply = nullptr;
+
+ const auto splitUrlPath = reqPath.split('/');
+ const auto shareId = splitUrlPath.last();
+
+ const auto existingShareIterator = std::find_if(_sharesReplyData.cbegin(), _sharesReplyData.cend(), [&shareId](const QJsonValue &value) {
+ return value.toObject().value("id").toString() == shareId;
+ });
+
+ if (existingShareIterator == _sharesReplyData.cend()) {
+ reply = new FakeErrorReply(op, req, this, 404, _fake404Response);
+ } else {
+ _sharesReplyData.removeAt(existingShareIterator - _sharesReplyData.cbegin());
+ reply = new FakePayloadReply(op, req, _fake200JsonResponse, searchResultsReplyDelay, _fakeQnam.data());
+ }
+
+ return reply;
+}
+
+QNetworkReply *ShareTestHelper::handleShareGetOperation(const QNetworkAccessManager::Operation op, const QNetworkRequest &req, const QString &reqPath)
+{
+ QNetworkReply *reply = nullptr;
+
+ // Properly formatted request to fetch shares goes something like:
+ // GET https://somehost/owncloud/ocs/v2.php/apps/files_sharing/api/v1/shares?path=file.md&reshares=true&format=json
+ // Header: { Ocs-APIREQUEST: true, Content-Type: application/x-www-form-urlencoded, X-Request-ID: 8ba8960d-ca0d-45ba-abf4-03ab95ba6064, }
+ // Data: []
+ const auto urlQuery = QUrlQuery(req.url());
+ const auto pathParam = urlQuery.queryItemValue(QStringLiteral("path"));
+ const auto resharesParam = urlQuery.queryItemValue(QStringLiteral("reshares"));
+ const auto formatParam = urlQuery.queryItemValue(QStringLiteral("format"));
+
+ if (formatParam != QStringLiteral("json") || (!pathParam.isEmpty() && !pathParam.endsWith(QString(testFileName)))) {
+ reply = new FakeErrorReply(op, req, this, 400, _fake400Response);
+ } else if (reqPath.contains(QStringLiteral("ocs/v2.php/apps/files_sharing/api/v1/shares"))) {
+ reply = new FakePayloadReply(op, req, jsonValueToOccReply(_sharesReplyData), searchResultsReplyDelay, _fakeQnam.data());
+ }
+
+ return reply;
+}
+
+const QByteArray ShareTestHelper::createNewShare(const Share::ShareType shareType, const QString &shareWith, const QString &password)
+{
+ const auto displayString = shareType == Share::TypeLink ? QString() : shareWith;
+ const FakeShareDefinition newShareDefinition(this,
+ shareType,
+ shareWith,
+ displayString,
+ password);
+
+ _sharesReplyData.append(newShareDefinition.toShareJsonObject());
+ return newShareDefinition.toRequestReply();
+}
+
+int ShareTestHelper::shareCount() const
+{
+ return _sharesReplyData.count();
+}
+
+void ShareTestHelper::appendShareReplyData(const FakeShareDefinition &definition)
+{
+ _sharesReplyData.append(definition.toShareJsonObject());
+}
+
+void ShareTestHelper::resetTestShares()
+{
+ _sharesReplyData = QJsonArray();
+}
+
+void ShareTestHelper::resetTestData()
+{
+ resetTestShares();
+ account->setCapabilities(_fakeCapabilities);
+}
diff --git a/test/sharetestutils.h b/test/sharetestutils.h
new file mode 100644
index 000000000..c539547fe
--- /dev/null
+++ b/test/sharetestutils.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <QObject>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+
+#include "gui/accountmanager.h"
+#include "gui/folderman.h"
+#include "gui/sharemanager.h"
+
+#include "syncenginetestutils.h"
+
+using namespace OCC;
+
+struct FakeFileReplyDefinition
+{
+ QString fileOwnerUid;
+ QString fileOwnerDisplayName;
+ QString fileTarget;
+ bool fileHasPreview;
+ QString fileFileParent;
+ QString fileSource;
+ QString fileItemSource;
+ QString fileItemType;
+ int fileMailSend;
+ QString fileMimeType;
+ QString fileParent;
+ QString filePath;
+ int fileStorage;
+ QString fileStorageId;
+};
+
+struct FakeShareDefinition
+{
+ FakeShareDefinition() = default;
+ FakeShareDefinition(ShareTestHelper *helper,
+ const Share::ShareType type,
+ const QString &shareWith,
+ const QString &displayString,
+ const QString &password = QString(),
+ const QString &note = QString(),
+ const QString &expiration = QString());
+
+ FakeFileReplyDefinition fileDefinition;
+ QString shareId;
+ bool shareCanDelete;
+ bool shareCanEdit;
+ QString shareUidOwner;
+ QString shareDisplayNameOwner;
+ QString sharePassword;
+ int sharePermissions;
+ QString shareNote;
+ int shareHideDownload;
+ QString shareExpiration;
+ bool shareSendPasswordByTalk;
+ int shareType;
+ QString shareShareWith;
+ QString shareShareWithDisplayName;
+ QString shareToken;
+ QString linkShareName;
+ QString linkShareLabel;
+ QString linkShareUrl;
+
+ [[nodiscard]] QJsonObject toShareJsonObject() const;
+ [[nodiscard]] QByteArray toRequestReply() const;
+};
+
+class ShareTestHelper : public QObject
+{
+ Q_OBJECT
+
+public:
+ ShareTestHelper(QObject *parent = nullptr);
+ ~ShareTestHelper() override;
+
+ FolderMan fm;
+ FakeFolder fakeFolder{FileInfo{}};
+ FakeFileReplyDefinition fakeFileDefinition;
+
+ AccountPtr account;
+ AccountStatePtr accountState;
+
+ int latestShareId = 0;
+
+ static constexpr auto testFileName = "file.md";
+ static constexpr auto searchResultsReplyDelay = 100;
+ static constexpr auto expectedDtFormat = "yyyy-MM-dd 00:00:00";
+
+ const QByteArray createNewShare(const Share::ShareType shareType, const QString &shareWith, const QString &password);
+ [[nodiscard]] int shareCount() const;
+
+signals:
+ void setupSucceeded();
+
+public slots:
+ void setup();
+ void appendShareReplyData(const FakeShareDefinition &definition);
+ void resetTestShares();
+ void resetTestData();
+
+private slots:
+ [[nodiscard]] QNetworkReply *qnamOverride(const QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device);
+ [[nodiscard]] QNetworkReply *handleSharePostOperation(const QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device);
+ [[nodiscard]] QNetworkReply *handleSharePutOperation(const QNetworkAccessManager::Operation op, const QNetworkRequest &req, const QString &reqPath, QIODevice *device);
+ [[nodiscard]] QNetworkReply *handleShareDeleteOperation(const QNetworkAccessManager::Operation op, const QNetworkRequest &req, const QString &reqPath);
+ [[nodiscard]] QNetworkReply *handleShareGetOperation(const QNetworkAccessManager::Operation op, const QNetworkRequest &req, const QString &reqPath);
+
+private:
+ QScopedPointer<FakeQNAM> _fakeQnam;
+
+ QByteArray _fake404Response = R"({"ocs":{"meta":{"status":"failure","statuscode":404,"message":"Invalid query, please check the syntax. API specifications are here: http:\/\/www.freedesktop.org\/wiki\/Specifications\/open-collaboration-services.\n"},"data":[]}})";
+ QByteArray _fake403Response = R"({"ocs":{"meta":{"status":"failure","statuscode":403,"message":"Operation not allowed."},"data":[]}})";
+ QByteArray _fake400Response = R"({"ocs":{"meta":{"status":"failure","statuscode":400,"message":"Parameter is incorrect.\n"},"data":[]}})";
+ QByteArray _fake200JsonResponse = R"({"ocs":{"data":[],"meta":{"message":"OK","status":"ok","statuscode":200}}})";
+
+ QJsonArray _sharesReplyData;
+ QVariantMap _fakeCapabilities;
+ QSet<int> _liveShareIds;
+};
diff --git a/test/testhelper.cpp b/test/testhelper.cpp
index 8ba0f151b..2a540965f 100644
--- a/test/testhelper.cpp
+++ b/test/testhelper.cpp
@@ -1,4 +1,6 @@
#include "testhelper.h"
+#include <QJsonObject>
+#include <QJsonDocument>
OCC::FolderDefinition folderDefinition(const QString &path)
{
@@ -8,3 +10,19 @@ OCC::FolderDefinition folderDefinition(const QString &path)
d.alias = path;
return d;
}
+
+
+const QByteArray jsonValueToOccReply(const QJsonValue &jsonValue)
+{
+ QJsonObject root;
+ QJsonObject ocs;
+ QJsonObject meta;
+
+ meta.insert("statuscode", 200);
+
+ ocs.insert(QStringLiteral("data"), jsonValue);
+ ocs.insert(QStringLiteral("meta"), meta);
+ root.insert(QStringLiteral("ocs"), ocs);
+
+ return QJsonDocument(root).toJson();
+}
diff --git a/test/testhelper.h b/test/testhelper.h
index 40379577c..2ddb859e5 100644
--- a/test/testhelper.h
+++ b/test/testhelper.h
@@ -18,4 +18,6 @@ public:
OCC::FolderDefinition folderDefinition(const QString &path);
+const QByteArray jsonValueToOccReply(const QJsonValue &jsonValue);
+
#endif // TESTHELPER_H
diff --git a/test/testsharemodel.cpp b/test/testsharemodel.cpp
index 04c5fcd05..9a3b10853 100644
--- a/test/testsharemodel.cpp
+++ b/test/testsharemodel.cpp
@@ -15,627 +15,88 @@
#include "gui/filedetails/sharemodel.h"
#include <QTest>
+#include <QAbstractItemModelTester>
#include <QSignalSpy>
#include <QFileInfo>
#include <QFlags>
+#include <QDateTime>
+#include <QTimeZone>
-#include "accountmanager.h"
-#include "folderman.h"
-#include "syncenginetestutils.h"
-#include "testhelper.h"
+#include "sharetestutils.h"
#include "libsync/theme.h"
using namespace OCC;
-static QByteArray fake404Response = R"(
-{"ocs":{"meta":{"status":"failure","statuscode":404,"message":"Invalid query, please check the syntax. API specifications are here: http:\/\/www.freedesktop.org\/wiki\/Specifications\/open-collaboration-services.\n"},"data":[]}}
-)";
-
-static QByteArray fake403Response = R"(
-{"ocs":{"meta":{"status":"failure","statuscode":403,"message":"Operation not allowed."},"data":[]}}
-)";
-
-static QByteArray fake400Response = R"(
-{"ocs":{"meta":{"status":"failure","statuscode":400,"message":"Parameter is incorrect.\n"},"data":[]}}
-)";
-
-static QByteArray fake200JsonResponse = R"(
-{"ocs":{"data":[],"meta":{"message":"OK","status":"ok","statuscode":200}}}
-)";
-
-constexpr auto testFileName = "file.md";
-constexpr auto searchResultsReplyDelay = 100;
-constexpr auto expectedDtFormat = "yyyy-MM-dd 00:00:00";
-
class TestShareModel : public QObject
{
Q_OBJECT
-public:
- TestShareModel() = default;
- ~TestShareModel() override
- {
- const auto folder = FolderMan::instance()->folder(_fakeFolder.localPath());
- if (folder) {
- FolderMan::instance()->removeFolder(folder);
- }
- AccountManager::instance()->deleteAccount(_accountState.data());
- }
-
- struct FakeFileReplyDefinition
- {
- QString fileOwnerUid;
- QString fileOwnerDisplayName;
- QString fileTarget;
- bool fileHasPreview;
- QString fileFileParent;
- QString fileSource;
- QString fileItemSource;
- QString fileItemType;
- int fileMailSend;
- QString fileMimeType;
- QString fileParent;
- QString filePath;
- int fileStorage;
- QString fileStorageId;
- };
-
- struct FakeShareDefinition
- {
- FakeFileReplyDefinition fileDefinition;
- QString shareId;
- bool shareCanDelete;
- bool shareCanEdit;
- QString shareUidOwner;
- QString shareDisplayNameOwner;
- QString sharePassword;
- int sharePermissions;
- QString shareNote;
- int shareHideDownload;
- QString shareExpiration;
- bool shareSendPasswordByTalk;
- int shareType;
- QString shareShareWith;
- QString shareShareWithDisplayName;
- QString shareToken;
- QString linkShareName;
- QString linkShareLabel;
- QString linkShareUrl;
- };
-
- const QByteArray fakeSharesResponse() const
- {
- QJsonObject root;
- QJsonObject ocs;
- QJsonObject meta;
-
- meta.insert("statuscode", 200);
-
- ocs.insert(QStringLiteral("data"), _sharesReplyData);
- ocs.insert(QStringLiteral("meta"), meta);
- root.insert(QStringLiteral("ocs"), ocs);
-
- return QJsonDocument(root).toJson();
- }
-
- QJsonObject shareDefinitionToJson(const FakeShareDefinition &definition)
- {
- QJsonObject newShareJson;
- newShareJson.insert("uid_file_owner", definition.fileDefinition.fileOwnerUid);
- newShareJson.insert("displayname_file_owner", definition.fileDefinition.fileOwnerDisplayName);
- newShareJson.insert("file_target", definition.fileDefinition.fileTarget);
- newShareJson.insert("has_preview", definition.fileDefinition.fileHasPreview);
- newShareJson.insert("file_parent", definition.fileDefinition.fileFileParent);
- newShareJson.insert("file_source", definition.fileDefinition.fileSource);
- newShareJson.insert("item_source", definition.fileDefinition.fileItemSource);
- newShareJson.insert("item_type", definition.fileDefinition.fileItemType);
- newShareJson.insert("mail_send", definition.fileDefinition.fileMailSend);
- newShareJson.insert("mimetype", definition.fileDefinition.fileMimeType);
- newShareJson.insert("parent", definition.fileDefinition.fileParent);
- newShareJson.insert("path", definition.fileDefinition.filePath);
- newShareJson.insert("storage", definition.fileDefinition.fileStorage);
- newShareJson.insert("storage_id", definition.fileDefinition.fileStorageId);
- newShareJson.insert("id", definition.shareId);
- newShareJson.insert("can_delete", definition.shareCanDelete);
- newShareJson.insert("can_edit", definition.shareCanEdit);
- newShareJson.insert("uid_owner", definition.shareUidOwner);
- newShareJson.insert("displayname_owner", definition.shareDisplayNameOwner);
- newShareJson.insert("password", definition.sharePassword);
- newShareJson.insert("permissions", definition.sharePermissions);
- newShareJson.insert("note", definition.shareNote);
- newShareJson.insert("hide_download", definition.shareHideDownload);
- newShareJson.insert("expiration", definition.shareExpiration);
- newShareJson.insert("send_password_by_talk", definition.shareSendPasswordByTalk);
- newShareJson.insert("share_type", definition.shareType);
- newShareJson.insert("share_with", definition.shareShareWith); // Doesn't seem to make sense but is server behaviour
- newShareJson.insert("share_with_displayname", definition.shareShareWithDisplayName);
- newShareJson.insert("token", definition.shareToken);
- newShareJson.insert("name", definition.linkShareName);
- newShareJson.insert("label", definition.linkShareLabel);
- newShareJson.insert("url", definition.linkShareUrl);
-
- return newShareJson;
- }
-
- void appendShareReplyData(const FakeShareDefinition &definition)
- {
- const auto shareJson = shareDefinitionToJson(definition);
- _sharesReplyData.append(shareJson);
- }
-
- const QByteArray createNewShare(const Share::ShareType shareType, const QString &shareWith)
- {
- ++_latestShareId;
- const auto newShareId = QString::number(_latestShareId);
- const auto newShareCanDelete = true;
- const auto newShareCanEdit = true;
- const auto newShareUidOwner = _account->davUser();
- const auto newShareDisplayNameOwner = _account->davDisplayName();
- const auto newSharePassword = QString();
- const auto newSharePermissions = static_cast<int>(SharePermissions(SharePermissionRead |
- SharePermissionUpdate |
- SharePermissionCreate |
- SharePermissionDelete |
- SharePermissionShare));
- const auto newShareNote = QString();
- const auto newShareHideDownload = 0;
- const auto newShareExpiration = QString();
- const auto newShareSendPasswordByTalk = false;
- const auto newShareType = shareType;
- const auto newShareShareWith = shareType == Share::TypeLink ? newSharePassword : shareWith;
- const auto newShareShareWithDisplayName = shareType == Share::TypeLink ? QStringLiteral("(Shared Link)") : shareWith;
- const auto newShareToken = QString::number(qHash(newShareId + _fakeFileDefinition.filePath));
- const auto newLinkShareName = QString();
- const auto newLinkShareLabel = QString();
- const auto newLinkShareUrl = shareType == Share::TypeLink ? QString(_account->davUrl().toString() + QStringLiteral("/s/") + newShareToken) : QString();
-
- const FakeShareDefinition newShareDefinition {
- _fakeFileDefinition,
- newShareId,
- newShareCanDelete,
- newShareCanEdit,
- newShareUidOwner,
- newShareDisplayNameOwner,
- newSharePassword,
- newSharePermissions,
- newShareNote,
- newShareHideDownload,
- newShareExpiration,
- newShareSendPasswordByTalk,
- newShareType,
- newShareShareWith,
- newShareShareWithDisplayName,
- newShareToken,
- newLinkShareName,
- newLinkShareLabel,
- newLinkShareUrl,
- };
-
- const auto shareJson = shareDefinitionToJson(newShareDefinition);
- _sharesReplyData.append(shareJson);
- return shareWrappedAsReply(shareJson);
- }
-
- QByteArray shareWrappedAsReply(const QJsonObject &shareObject)
- {
- QJsonObject root;
- QJsonObject ocs;
- QJsonObject meta;
-
- meta.insert("statuscode", 200);
-
- ocs.insert(QStringLiteral("data"), shareObject);
- ocs.insert(QStringLiteral("meta"), meta);
- root.insert(QStringLiteral("ocs"), ocs);
-
- return QJsonDocument(root).toJson();
- }
-
- void resetTestData()
- {
- _sharesReplyData = QJsonArray();
- _account->setCapabilities(_fakeCapabilities);
- }
-
private:
- FolderMan _fm;
- FakeFolder _fakeFolder{FileInfo{}};
+ ShareTestHelper helper;
- AccountPtr _account;
- AccountStatePtr _accountState;
- QScopedPointer<FakeQNAM> _fakeQnam;
- FakeFileReplyDefinition _fakeFileDefinition;
FakeShareDefinition _testLinkShareDefinition;
FakeShareDefinition _testEmailShareDefinition;
FakeShareDefinition _testUserShareDefinition;
FakeShareDefinition _testRemoteShareDefinition;
- QJsonArray _sharesReplyData;
- QVariantMap _fakeCapabilities;
- QSet<int> _liveShareIds;
- int _latestShareId = 0;
private slots:
void initTestCase()
{
- _fakeQnam.reset(new FakeQNAM({}));
- _fakeQnam->setOverride([this](QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device) {
- QNetworkReply *reply = nullptr;
-
- const auto reqUrl = req.url();
- const auto reqRawPath = reqUrl.path();
- const auto reqPath = reqRawPath.startsWith("/owncloud/") ? reqRawPath.mid(10) : reqRawPath;
- qDebug() << req.url() << reqPath << op;
-
- // Properly formatted PROPFIND URL goes something like:
- // https://cloud.nextcloud.com/remote.php/dav/files/claudio/Readme.md
- if(reqPath.endsWith(testFileName) && req.attribute(QNetworkRequest::CustomVerbAttribute) == "PROPFIND") {
-
- reply = new FakePropfindReply(_fakeFolder.remoteModifier(), op, req, this);
-
- } else if (req.url().toString().startsWith(_accountState->account()->url().toString()) &&
- reqPath.startsWith(QStringLiteral("ocs/v2.php/apps/files_sharing/api/v1/shares")) &&
- op == QNetworkAccessManager::PostOperation) {
-
- // POST https://somehost/owncloud/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json
- // Header: { Ocs-APIREQUEST: true, Content-Type: application/x-www-form-urlencoded, X-Request-ID: 1527752d-e147-4da7-89b8-fb06315a5fad, }
- // Data: [path=file.md&shareType=3]"
- const QUrlQuery urlQuery(req.url());
- const auto formatParam = urlQuery.queryItemValue(QStringLiteral("format"));
-
- if (formatParam == QStringLiteral("json")) {
- device->open(QIODevice::ReadOnly);
- const auto requestBody = device->readAll();
- device->close();
-
- const auto requestData = requestBody.split('&');
- // We don't care about path since we know the file we are testing with
- auto requestShareType = -10; // Just in case
- QString requestShareWith;
- QString requestName;
- QString requestPassword;
-
- for(const auto &data : requestData) {
- const auto requestDataUrl = QUrl::fromPercentEncoding(data);
- const QString requestDataUrlString(requestDataUrl);
-
- if (data.contains("shareType=")) {
- const auto shareTypeString = requestDataUrlString.mid(10);
- requestShareType = Share::ShareType(shareTypeString.toInt());
- } else if (data.contains("shareWith=")) {
- requestShareWith = data.mid(10);
- } else if (data.contains("name=")) {
- requestName = data.mid(5);
- } else if (data.contains("password=")) {
- requestPassword = data.mid(9);
- }
- }
-
- if (requestPassword.isEmpty() &&
- ((requestShareType == Share::TypeEmail && _account->capabilities().shareEmailPasswordEnforced()) ||
- (requestShareType == Share::TypeLink && _account->capabilities().sharePublicLinkEnforcePassword()))) {
-
- reply = new FakePayloadReply(op, req, fake403Response, searchResultsReplyDelay, _fakeQnam.data());
-
- } else if (requestShareType >= 0) {
- const auto shareType = Share::ShareType(requestShareType);
- reply = new FakePayloadReply(op, req, createNewShare(shareType, requestShareWith), searchResultsReplyDelay, _fakeQnam.data());
- }
- }
-
- } else if(req.url().toString().startsWith(_accountState->account()->url().toString()) &&
- reqPath.startsWith(QStringLiteral("ocs/v2.php/apps/files_sharing/api/v1/shares")) &&
- req.attribute(QNetworkRequest::CustomVerbAttribute) == "DELETE") {
-
- const auto splitUrlPath = reqPath.split('/');
- const auto shareId = splitUrlPath.last();
-
- const auto existingShareIterator = std::find_if(_sharesReplyData.cbegin(), _sharesReplyData.cend(), [&shareId](const QJsonValue &value) {
- return value.toObject().value("id").toString() == shareId;
- });
-
- if (existingShareIterator == _sharesReplyData.cend()) {
- reply = new FakeErrorReply(op, req, this, 404, fake404Response);
- } else {
- _sharesReplyData.removeAt(existingShareIterator - _sharesReplyData.cbegin());
- reply = new FakePayloadReply(op, req, fake200JsonResponse, searchResultsReplyDelay, _fakeQnam.data());
- }
-
- } else if(req.url().toString().startsWith(_accountState->account()->url().toString()) &&
- reqPath.startsWith(QStringLiteral("ocs/v2.php/apps/files_sharing/api/v1/shares")) &&
- op == QNetworkAccessManager::PutOperation) {
-
- const auto splitUrlPath = reqPath.split('/');
- const auto shareId = splitUrlPath.last();
-
- const QUrlQuery urlQuery(req.url());
- const auto formatParam = urlQuery.queryItemValue(QStringLiteral("format"));
-
- if (formatParam == QStringLiteral("json")) {
- device->open(QIODevice::ReadOnly);
- const auto requestBody = device->readAll();
- device->close();
-
- const auto requestData = requestBody.split('&');
-
- const auto existingShareIterator = std::find_if(_sharesReplyData.cbegin(), _sharesReplyData.cend(), [&shareId](const QJsonValue &value) {
- return value.toObject().value("id").toString() == shareId;
- });
-
- if (existingShareIterator == _sharesReplyData.cend()) {
- reply = new FakeErrorReply(op, req, this, 404, fake404Response);
- } else {
- const auto existingShareValue = *existingShareIterator;
- auto shareObject = existingShareValue.toObject();
-
- for (const auto &requestDataItem : requestData) {
- const auto requestSplit = requestDataItem.split('=');
- auto requestKey = requestSplit.first();
- auto requestValue = requestSplit.last();
-
- // We send expireDate without time but the server returns with time at 00:00:00
- if (requestKey == "expireDate") {
- requestKey = "expiration";
- requestValue.append(" 00:00:00");
- }
-
- shareObject.insert(QString(requestKey), QString(requestValue));
- }
-
- _sharesReplyData.replace(existingShareIterator - _sharesReplyData.cbegin(), shareObject);
- reply = new FakePayloadReply(op, req, shareWrappedAsReply(shareObject), searchResultsReplyDelay, _fakeQnam.data());
- }
- }
-
- } else if(req.url().toString().startsWith(_accountState->account()->url().toString()) &&
- reqPath.startsWith(QStringLiteral("ocs/v2.php/apps/files_sharing/api/v1/shares")) &&
- req.attribute(QNetworkRequest::CustomVerbAttribute) == "GET") {
-
- // Properly formatted request to fetch shares goes something like:
- // GET https://somehost/owncloud/ocs/v2.php/apps/files_sharing/api/v1/shares?path=file.md&reshares=true&format=json
- // Header: { Ocs-APIREQUEST: true, Content-Type: application/x-www-form-urlencoded, X-Request-ID: 8ba8960d-ca0d-45ba-abf4-03ab95ba6064, }
- // Data: []
- const auto urlQuery = QUrlQuery(req.url());
- const auto pathParam = urlQuery.queryItemValue(QStringLiteral("path"));
- const auto resharesParam = urlQuery.queryItemValue(QStringLiteral("reshares"));
- const auto formatParam = urlQuery.queryItemValue(QStringLiteral("format"));
-
- if (formatParam != QStringLiteral("json") || (!pathParam.isEmpty() && pathParam != QString(testFileName))) {
- reply = new FakeErrorReply(op, req, this, 400, fake400Response);
- } else if (reqPath.contains(QStringLiteral("ocs/v2.php/apps/files_sharing/api/v1/shares"))) {
- reply = new FakePayloadReply(op, req, fakeSharesResponse(), searchResultsReplyDelay, _fakeQnam.data());
- }
-
- } else if (!req.url().toString().startsWith(_accountState->account()->url().toString())) {
- reply = new FakeErrorReply(op, req, this, 404, fake404Response);
- } else if (!reply) {
- return qobject_cast<QNetworkReply*>(new FakeErrorReply(op, req, this, 404, QByteArrayLiteral("{error: \"Not found!\"}")));
- }
-
- return reply;
- });
-
- _fakeCapabilities = QVariantMap {
- {QStringLiteral("files_sharing"), QVariantMap {
- {QStringLiteral("api_enabled"), true},
- {QStringLiteral("default_permissions"), 19},
- {QStringLiteral("public"), QVariantMap {
- {QStringLiteral("enabled"), true},
- {QStringLiteral("expire_date"), QVariantMap {
- {QStringLiteral("days"), 30},
- {QStringLiteral("enforced"), false},
- }},
- {QStringLiteral("expire_date_internal"), QVariantMap {
- {QStringLiteral("days"), 30},
- {QStringLiteral("enforced"), false},
- }},
- {QStringLiteral("expire_date_remote"), QVariantMap {
- {QStringLiteral("days"), 30},
- {QStringLiteral("enforced"), false},
- }},
- {QStringLiteral("password"), QVariantMap {
- {QStringLiteral("enforced"), false},
- }},
- }},
- {QStringLiteral("sharebymail"), QVariantMap {
- {QStringLiteral("enabled"), true},
- {QStringLiteral("password"), QVariantMap {
- {QStringLiteral("enforced"), false},
- }},
- }},
- }},
- };
-
- _account = Account::create();
- _account->setCredentials(new FakeCredentials{_fakeQnam.data()});
- _account->setUrl(QUrl(("owncloud://somehost/owncloud")));
- _account->setCapabilities(_fakeCapabilities);
- _accountState = new AccountState(_account);
- AccountManager::instance()->addAccount(_account);
-
- QCOMPARE(_fakeFolder.currentLocalState(), _fakeFolder.currentRemoteState());
- _fakeFolder.localModifier().insert(testFileName);
-
- const auto folderMan = FolderMan::instance();
- QCOMPARE(folderMan, &_fm);
- QVERIFY(folderMan->addFolder(_accountState.data(), folderDefinition(_fakeFolder.localPath())));
- const auto folder = FolderMan::instance()->folder(_fakeFolder.localPath());
- QVERIFY(folder);
- QVERIFY(_fakeFolder.syncOnce());
- QCOMPARE(_fakeFolder.currentLocalState(), _fakeFolder.currentRemoteState());
- ItemCompletedSpy completeSpy(_fakeFolder);
-
- const auto fakeFileInfo = _fakeFolder.remoteModifier().find(testFileName);
- QVERIFY(fakeFileInfo);
- fakeFileInfo->permissions.setPermission(RemotePermissions::CanReshare);
- QVERIFY(_fakeFolder.syncOnce());
- QCOMPARE(_fakeFolder.currentLocalState(), _fakeFolder.currentRemoteState());
- QVERIFY(fakeFileInfo->permissions.CanReshare);
-
- // Generate test data
- // Properties that apply to the file generally
- const auto fileOwnerUid = _account->davUser();
- const auto fileOwnerDisplayName = _account->davDisplayName();
- const auto fileTarget = QString(QStringLiteral("/") + fakeFileInfo->name);
- const auto fileHasPreview = true;
- const auto fileFileParent = QString(_fakeFolder.remoteModifier().fileId);
- const auto fileSource = QString(fakeFileInfo->fileId);
- const auto fileItemSource = fileSource;
- const auto fileItemType = QStringLiteral("file");
- const auto fileMailSend = 0;
- const auto fileMimeType = QStringLiteral("text/markdown");
- const auto fileParent = QString();
- const auto filePath = fakeFileInfo->path();
- const auto fileStorage = 3;
- const auto fileStorageId = QString(QStringLiteral("home::") + _account->davUser());
-
- _fakeFileDefinition = FakeFileReplyDefinition {
- fileOwnerUid,
- fileOwnerDisplayName,
- fileTarget,
- fileHasPreview,
- fileFileParent,
- fileSource,
- fileItemSource,
- fileItemType,
- fileMailSend,
- fileMimeType,
- fileParent,
- filePath,
- fileStorage,
- fileStorageId,
- };
+ QSignalSpy helperSetupSucceeded(&helper, &ShareTestHelper::setupSucceeded);
+ helper.setup();
+ QCOMPARE(helperSetupSucceeded.count(), 1);
const auto testSharePassword = "3|$argon2id$v=19$m=65536,"
"t=4,"
"p=1$M2FoLnliWkhIZkwzWjFBQg$BPraP+JUqP1sV89rkymXpCGxHBlCct6bZ39xUGaYQ5w";
- const auto testShareToken = "GQ4aLrZEdJJkopW";
- const auto testShareCanDelete = true;
- const auto testShareCanEdit = true;
- const auto testShareUidOwner = _account->davUser();
- const auto testShareDisplayNameOwner = _account->davDisplayName();
- const auto testSharePermissions = static_cast<int>(SharePermissions(SharePermissionRead |
- SharePermissionUpdate |
- SharePermissionCreate |
- SharePermissionDelete |
- SharePermissionShare));
const auto testShareNote = QStringLiteral("This is a note!");
- const auto testShareHideDownload = 0;
- const auto testShareExpiration = QDate::currentDate().addDays(1).toString(expectedDtFormat);
- const auto testShareSendPasswordByTalk = false;
-
- ++_latestShareId;
- const auto linkShareShareWith = testSharePassword; // Weird, but it's what the server does
- const auto linkShareShareWithDisplayName = QStringLiteral("(Shared Link)");
- const auto linkShareUrl = QString(_account->davUrl().toString() + QStringLiteral("/s/") + testShareToken);
-
- _testLinkShareDefinition = FakeShareDefinition {
- _fakeFileDefinition,
- QString::number(_latestShareId),
- testShareCanDelete,
- testShareCanEdit,
- testShareUidOwner,
- testShareDisplayNameOwner,
- testSharePassword,
- testSharePermissions,
- testShareNote,
- testShareHideDownload,
- testShareExpiration,
- testShareSendPasswordByTalk,
- Share::TypeLink,
- linkShareShareWith,
- linkShareShareWithDisplayName,
- testShareToken,
- QStringLiteral("Link share name"),
- QStringLiteral("Link share label"),
- linkShareUrl,
- };
+ const auto testShareExpiration = QDate::currentDate().addDays(1).toString(helper.expectedDtFormat);
+
+ const auto linkShareLabel = QStringLiteral("Link share label");
+ _testLinkShareDefinition = FakeShareDefinition(&helper,
+ Share::TypeLink,
+ {},
+ linkShareLabel,
+ testSharePassword,
+ testShareNote,
+ testShareExpiration);
- ++_latestShareId;
const auto emailShareShareWith = QStringLiteral("test-email@nextcloud.com");
const auto emailShareShareWithDisplayName = QStringLiteral("Test email");
+ _testEmailShareDefinition = FakeShareDefinition(&helper,
+ Share::TypeEmail,
+ emailShareShareWith,
+ emailShareShareWithDisplayName,
+ testSharePassword,
+ testShareNote,
+ testShareExpiration);
- _testEmailShareDefinition = FakeShareDefinition {
- _fakeFileDefinition,
- QString::number(_latestShareId),
- testShareCanDelete,
- testShareCanEdit,
- testShareUidOwner,
- testShareDisplayNameOwner,
- testSharePassword,
- testSharePermissions,
- testShareNote,
- testShareHideDownload,
- testShareExpiration,
- testShareSendPasswordByTalk,
- Share::TypeEmail,
- emailShareShareWith,
- emailShareShareWithDisplayName,
- testShareToken,
- {},
- {},
- {},
- };
- ++_latestShareId;
const auto userShareShareWith = QStringLiteral("user");
const auto userShareShareWithDisplayName("A Nextcloud user");
+ _testUserShareDefinition = FakeShareDefinition(&helper,
+ Share::TypeUser,
+ userShareShareWith,
+ userShareShareWithDisplayName);
+
- _testUserShareDefinition = FakeShareDefinition {
- _fakeFileDefinition,
- QString::number(_latestShareId),
- testShareCanDelete,
- testShareCanEdit,
- testShareUidOwner,
- testShareDisplayNameOwner,
- testSharePassword,
- testSharePermissions,
- testShareNote,
- testShareHideDownload,
- testShareExpiration,
- testShareSendPasswordByTalk,
- Share::TypeUser,
- userShareShareWith,
- userShareShareWithDisplayName,
- testShareToken,
- {},
- {},
- {},
- };
- ++_latestShareId;
const auto remoteShareShareWith = QStringLiteral("remote_share");
const auto remoteShareShareWithDisplayName("A remote share");
-
- _testRemoteShareDefinition = FakeShareDefinition {
- _fakeFileDefinition,
- QString::number(_latestShareId),
- testShareCanDelete,
- testShareCanEdit,
- testShareUidOwner,
- testShareDisplayNameOwner,
- testSharePassword,
- testSharePermissions,
- testShareNote,
- testShareHideDownload,
- testShareExpiration,
- testShareSendPasswordByTalk,
- Share::TypeRemote,
- remoteShareShareWith,
- remoteShareShareWithDisplayName,
- testShareToken,
- {},
- {},
- {},
- };
+ _testRemoteShareDefinition = FakeShareDefinition(&helper,
+ Share::TypeRemote,
+ remoteShareShareWith,
+ remoteShareShareWithDisplayName);
qRegisterMetaType<ShareePtr>("ShareePtr");
}
void testSetAccountAndPath()
{
- resetTestData();
+ helper.resetTestData();
// Test with a link share
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -648,16 +109,16 @@ private slots:
QSignalSpy sharingEnabledChanged(&model, &ShareModel::sharingEnabledChanged);
QSignalSpy publicLinkSharesEnabledChanged(&model, &ShareModel::publicLinkSharesEnabledChanged);
- model.setAccountState(_accountState.data());
+ model.setAccountState(helper.accountState.data());
QCOMPARE(accountStateChanged.count(), 1);
// Check all the account-related properties of the model
- QCOMPARE(model.accountConnected(), _accountState->isConnected());
- QCOMPARE(model.sharingEnabled(), _account->capabilities().shareAPI());
- QCOMPARE(model.publicLinkSharesEnabled() && Theme::instance()->linkSharing(), _account->capabilities().sharePublicLink());
+ QCOMPARE(model.accountConnected(), helper.accountState->isConnected());
+ QCOMPARE(model.sharingEnabled(), helper.account->capabilities().shareAPI());
+ QCOMPARE(model.publicLinkSharesEnabled() && Theme::instance()->linkSharing(), helper.account->capabilities().sharePublicLink());
QCOMPARE(Theme::instance()->userGroupSharing(), model.userGroupSharingEnabled());
- const QString localPath(_fakeFolder.localPath() + testFileName);
+ const QString localPath(helper.fakeFolder.localPath() + helper.testFileName);
model.setLocalPath(localPath);
QCOMPARE(localPathChanged.count(), 1);
QCOMPARE(model.localPath(), localPath);
@@ -665,11 +126,12 @@ private slots:
void testSuccessfulFetchShares()
{
- resetTestData();
+ helper.resetTestData();
// Test with a link share and a user/group email share "from the server"
- appendShareReplyData(_testLinkShareDefinition);
- appendShareReplyData(_testEmailShareDefinition);
- appendShareReplyData(_testUserShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testEmailShareDefinition);
+ helper.appendShareReplyData(_testUserShareDefinition);
+ QCOMPARE(helper.shareCount(), 3);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -677,18 +139,18 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(model.rowCount(), helper.shareCount());
}
void testFetchSharesFailedError()
{
- resetTestData();
+ helper.resetTestData();
// Test with a link share "from the server"
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -697,8 +159,8 @@ private slots:
QSignalSpy serverError(&model, &ShareModel::serverError);
// Test fetching the shares of a file that does not exist
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + "wrong-filename-oops.md");
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + "wrong-filename-oops.md");
QVERIFY(serverError.wait(3000));
QCOMPARE(model.hasInitialShareFetchCompleted(), true);
QCOMPARE(model.rowCount(), 0); // Make sure no placeholder
@@ -706,10 +168,11 @@ private slots:
void testCorrectFetchOngoingSignalling()
{
- resetTestData();
+ helper.resetTestData();
// Test with a link share "from the server"
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -720,11 +183,11 @@ private slots:
// Make sure we are correctly signalling the loading state of the fetch
// Model resets twice when we set account and local path, resetting all model state.
- model.setAccountState(_accountState.data());
+ model.setAccountState(helper.accountState.data());
QCOMPARE(fetchOngoingChanged.count(), 1);
QCOMPARE(model.fetchOngoing(), false);
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
// If we can grab shares it then indicates fetch ongoing...
QCOMPARE(fetchOngoingChanged.count(), 3);
QCOMPARE(model.fetchOngoing(), true);
@@ -736,10 +199,11 @@ private slots:
void testCorrectInitialFetchCompleteSignalling()
{
- resetTestData();
+ helper.resetTestData();
// Test with a link share "from the server"
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -752,12 +216,12 @@ private slots:
// Make sure we are correctly signalling the loading state of the fetch
// Model resets twice when we set account and local path, resetting all model state.
- model.setAccountState(_accountState.data());
+ model.setAccountState(helper.accountState.data());
QCOMPARE(accountStateChanged.count(), 1);
QCOMPARE(hasInitialShareFetchCompletedChanged.count(), 1);
QCOMPARE(model.hasInitialShareFetchCompleted(), false);
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QCOMPARE(localPathChanged.count(), 1);
QCOMPARE(hasInitialShareFetchCompletedChanged.count(), 2);
QCOMPARE(model.hasInitialShareFetchCompleted(), false);
@@ -771,9 +235,10 @@ private slots:
// Link shares and user group shares have slightly different behaviour in model.data()
void testModelLinkShareData()
{
- resetTestData();
+ helper.resetTestData();
// Test with a link share "from the server"
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -781,11 +246,11 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(model.rowCount(), helper.shareCount());
const auto shareIndex = model.index(model.rowCount() - 1, 0, {});
QVERIFY(!shareIndex.data(Qt::DisplayRole).toString().isEmpty());
@@ -801,7 +266,7 @@ private slots:
QCOMPARE(shareIndex.data(ShareModel::PasswordRole).toString(), QString());
QCOMPARE(shareIndex.data(ShareModel::EditingAllowedRole).toBool(), SharePermissions(_testLinkShareDefinition.sharePermissions).testFlag(SharePermissionUpdate));
- const auto expectedLinkShareExpireDate = QDate::fromString(_testLinkShareDefinition.shareExpiration, expectedDtFormat);
+ const auto expectedLinkShareExpireDate = QDate::fromString(_testLinkShareDefinition.shareExpiration, helper.expectedDtFormat);
QCOMPARE(shareIndex.data(ShareModel::ExpireDateEnabledRole).toBool(), expectedLinkShareExpireDate.isValid());
QCOMPARE(shareIndex.data(ShareModel::ExpireDateRole).toLongLong(), expectedLinkShareExpireDate.startOfDay(Qt::UTC).toMSecsSinceEpoch());
@@ -811,9 +276,10 @@ private slots:
void testModelEmailShareData()
{
- resetTestData();
+ helper.resetTestData();
// Test with a user/group email share "from the server"
- appendShareReplyData(_testEmailShareDefinition);
+ helper.appendShareReplyData(_testEmailShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -821,8 +287,8 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
QCOMPARE(model.rowCount(), 2); // Remember about placeholder link share
@@ -838,7 +304,7 @@ private slots:
QCOMPARE(shareIndex.data(ShareModel::PasswordRole).toString(), QString());
QCOMPARE(shareIndex.data(ShareModel::EditingAllowedRole).toBool(), SharePermissions(_testEmailShareDefinition.sharePermissions).testFlag(SharePermissionUpdate));
- const auto expectedShareExpireDate = QDate::fromString(_testEmailShareDefinition.shareExpiration, expectedDtFormat);
+ const auto expectedShareExpireDate = QDate::fromString(_testEmailShareDefinition.shareExpiration, helper.expectedDtFormat);
QCOMPARE(shareIndex.data(ShareModel::ExpireDateEnabledRole).toBool(), expectedShareExpireDate.isValid());
QCOMPARE(shareIndex.data(ShareModel::ExpireDateRole).toLongLong(), expectedShareExpireDate.startOfDay(Qt::UTC).toMSecsSinceEpoch());
@@ -848,9 +314,10 @@ private slots:
void testModelUserShareData()
{
- resetTestData();
+ helper.resetTestData();
// Test with a user/group user share "from the server"
- appendShareReplyData(_testUserShareDefinition);
+ helper.appendShareReplyData(_testUserShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -858,8 +325,8 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
QCOMPARE(model.rowCount(), 2); // Remember about placeholder link share
@@ -875,7 +342,7 @@ private slots:
QCOMPARE(shareIndex.data(ShareModel::PasswordRole).toString(), QString());
QCOMPARE(shareIndex.data(ShareModel::EditingAllowedRole).toBool(), SharePermissions(_testUserShareDefinition.sharePermissions).testFlag(SharePermissionUpdate));
- const auto expectedShareExpireDate = QDate::fromString(_testUserShareDefinition.shareExpiration, expectedDtFormat);
+ const auto expectedShareExpireDate = QDate::fromString(_testUserShareDefinition.shareExpiration, helper.expectedDtFormat);
QCOMPARE(shareIndex.data(ShareModel::ExpireDateEnabledRole).toBool(), expectedShareExpireDate.isValid());
QCOMPARE(shareIndex.data(ShareModel::ExpireDateRole).toLongLong(), expectedShareExpireDate.startOfDay(Qt::UTC).toMSecsSinceEpoch());
@@ -885,17 +352,18 @@ private slots:
// Check correct user avatar
const auto avatarUrl = shareIndex.data(ShareModel::AvatarUrlRole).toString();
const auto relativeAvatarPath = QString("remote.php/dav/avatars/%1/%2.png").arg(_testUserShareDefinition.shareShareWith, QString::number(64));
- const auto expectedAvatarPath = Utility::concatUrlPath(_account->url(), relativeAvatarPath).toString();
+ const auto expectedAvatarPath = Utility::concatUrlPath(helper.account->url(), relativeAvatarPath).toString();
const QString expectedUrl(QStringLiteral("image://tray-image-provider/") + expectedAvatarPath);
QCOMPARE(avatarUrl, expectedUrl);
}
void testSuccessfulCreateShares()
{
- resetTestData();
+ helper.resetTestData();
// Test with an existing link share
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -903,18 +371,18 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Test if it gets added
model.createNewLinkShare();
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 2); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 2); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Test if it's the type we wanted
const auto newLinkShareIndex = model.index(model.rowCount() - 1, 0, {});
@@ -924,8 +392,8 @@ private slots:
const ShareePtr sharee(new Sharee("testsharee@nextcloud.com", "Test sharee", Sharee::Type::Email));
model.createNewUserGroupShare(sharee);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 3); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 3); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Test if it's the type we wanted
const auto newUserGroupShareIndex = model.index(model.rowCount() - 1, 0, {});
@@ -935,20 +403,20 @@ private slots:
const auto password = QStringLiteral("a pretty bad password but good thing it doesn't matter!");
model.createNewLinkShareWithPassword(password);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 4); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 4); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
model.createNewUserGroupShareWithPassword(sharee, password);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 5); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 5); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
- resetTestData();
+ helper.resetTestData();
}
void testEnforcePasswordShares()
{
- resetTestData();
+ helper.resetTestData();
// Enforce passwords for shares in capabilities
const QVariantMap enforcePasswordsCapabilities {
@@ -982,12 +450,13 @@ private slots:
}},
};
- _account->setCapabilities(enforcePasswordsCapabilities);
- QVERIFY(_account->capabilities().sharePublicLinkEnforcePassword());
- QVERIFY(_account->capabilities().shareEmailPasswordEnforced());
+ helper.account->setCapabilities(enforcePasswordsCapabilities);
+ QVERIFY(helper.account->capabilities().sharePublicLinkEnforcePassword());
+ QVERIFY(helper.account->capabilities().shareEmailPasswordEnforced());
// Test with a link share "from the server"
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -995,11 +464,11 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Confirm that the model requests a password
QSignalSpy requestPasswordForLinkShare(&model, &ShareModel::requestPasswordForLinkShare);
@@ -1014,11 +483,12 @@ private slots:
// Test that the model data is correctly reporting that passwords are enforced
const auto shareIndex = model.index(model.rowCount() - 1, 0, {});
QCOMPARE(shareIndex.data(ShareModel::PasswordEnforcedRole).toBool(), true);
+ QCOMPARE(shareIndex.data(ShareModel::PasswordProtectEnabledRole).toBool(), true);
}
void testEnforceExpireDate()
{
- resetTestData();
+ helper.resetTestData();
const auto internalExpireDays = 45;
const auto publicExpireDays = 30;
@@ -1056,15 +526,16 @@ private slots:
}},
};
- _account->setCapabilities(enforcePasswordsCapabilities);
- QVERIFY(_account->capabilities().sharePublicLinkEnforceExpireDate());
- QVERIFY(_account->capabilities().shareInternalEnforceExpireDate());
- QVERIFY(_account->capabilities().shareRemoteEnforceExpireDate());
+ helper.account->setCapabilities(enforcePasswordsCapabilities);
+ QVERIFY(helper.account->capabilities().sharePublicLinkEnforceExpireDate());
+ QVERIFY(helper.account->capabilities().shareInternalEnforceExpireDate());
+ QVERIFY(helper.account->capabilities().shareRemoteEnforceExpireDate());
// Test with shares "from the server"
- appendShareReplyData(_testLinkShareDefinition);
- appendShareReplyData(_testEmailShareDefinition);
- appendShareReplyData(_testRemoteShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testEmailShareDefinition);
+ helper.appendShareReplyData(_testRemoteShareDefinition);
+ QCOMPARE(helper.shareCount(), 3);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1072,11 +543,11 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Test that the model data is correctly reporting that expire dates are enforced for all share types
for(auto i = 0; i < model.rowCount(); ++i) {
@@ -1108,10 +579,11 @@ private slots:
void testSuccessfulDeleteShares()
{
- resetTestData();
+ helper.resetTestData();
// Test with an existing link share
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1119,33 +591,33 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Create share
model.createNewLinkShare();
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 2); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 2); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Test if it gets deleted properly
const auto latestLinkShare = model.index(model.rowCount() - 1, 0, {}).data(ShareModel::ShareRole).value<SharePtr>();
QSignalSpy shareDeleted(latestLinkShare.data(), &LinkShare::shareDeleted);
model.deleteShare(latestLinkShare);
QVERIFY(shareDeleted.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
- resetTestData();
+ helper.resetTestData();
}
void testPlaceholderLinkShare()
{
- resetTestData();
+ helper.resetTestData();
// Start with no shares; should show the placeholder link share
ShareModel model;
@@ -1154,8 +626,8 @@ private slots:
QSignalSpy hasInitialShareFetchCompletedChanged(&model, &ShareModel::hasInitialShareFetchCompletedChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(hasInitialShareFetchCompletedChanged.wait(5000));
QVERIFY(model.hasInitialShareFetchCompleted());
QCOMPARE(model.rowCount(), 1); // There should be a placeholder now
@@ -1168,8 +640,8 @@ private slots:
const ShareePtr sharee(new Sharee("testsharee@nextcloud.com", "Test sharee", Sharee::Type::Email));
model.createNewUserGroupShare(sharee);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count() + 1);
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount() + 1);
QVERIFY(placeholderLinkShareIndex.isValid());
QCOMPARE(placeholderLinkShareIndex.data(ShareModel::ShareTypeRole).toInt(), Share::TypePlaceholderLink);
@@ -1177,8 +649,8 @@ private slots:
// Now try adding a link share, which should remove the placeholder
model.createNewLinkShare();
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 2); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 2); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
QVERIFY(!placeholderLinkShareIndex.isValid());
@@ -1187,21 +659,22 @@ private slots:
QSignalSpy shareDeleted(latestLinkShare.data(), &LinkShare::shareDeleted);
model.deleteShare(latestLinkShare);
QVERIFY(shareDeleted.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count() + 1);
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount() + 1);
const auto newPlaceholderLinkShareIndex = model.index(model.rowCount() - 1, 0, {});
QCOMPARE(newPlaceholderLinkShareIndex.data(ShareModel::ShareTypeRole).toInt(), Share::TypePlaceholderLink);
- resetTestData();
+ helper.resetTestData();
}
void testSuccessfulToggleAllowEditing()
{
- resetTestData();
+ helper.resetTestData();
// Test with an existing link share
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1209,12 +682,12 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
const auto shareIndex = model.index(model.rowCount() - 1, 0, {});
QCOMPARE(shareIndex.data(ShareModel::EditingAllowedRole).toBool(), SharePermissions(_testLinkShareDefinition.sharePermissions).testFlag(SharePermissionUpdate));
@@ -1229,11 +702,12 @@ private slots:
void testSuccessfulPasswordSet()
{
- resetTestData();
+ helper.resetTestData();
// Test with an existing link share.
// This one has a pre-existing password
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1241,12 +715,12 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
const auto shareIndex = model.index(model.rowCount() - 1, 0, {});
QCOMPARE(shareIndex.data(ShareModel::PasswordProtectEnabledRole).toBool(), true);
@@ -1269,11 +743,12 @@ private slots:
void testSuccessfulExpireDateSet()
{
- resetTestData();
+ helper.resetTestData();
// Test with an existing link share.
// This one has a pre-existing expire date
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1281,12 +756,12 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Check what we know
const auto shareIndex = model.index(model.rowCount() - 1, 0, {});
@@ -1318,11 +793,12 @@ private slots:
void testSuccessfulNoteSet()
{
- resetTestData();
+ helper.resetTestData();
// Test with an existing link share.
// This one has a pre-existing password
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1330,12 +806,12 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
const auto shareIndex = model.index(model.rowCount() - 1, 0, {});
QCOMPARE(shareIndex.data(ShareModel::NoteEnabledRole).toBool(), true);
@@ -1359,10 +835,11 @@ private slots:
void testSuccessfulLinkShareLabelSet()
{
- resetTestData();
+ helper.resetTestData();
// Test with an existing link share.
- appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1370,12 +847,12 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
const auto shareIndex = model.index(model.rowCount() - 1, 0, {});
QCOMPARE(shareIndex.data(ShareModel::LinkShareLabelRole).toBool(), true);
@@ -1391,11 +868,12 @@ private slots:
void testSharees()
{
- resetTestData();
+ helper.resetTestData();
- appendShareReplyData(_testLinkShareDefinition);
- appendShareReplyData(_testEmailShareDefinition);
- appendShareReplyData(_testUserShareDefinition);
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ helper.appendShareReplyData(_testEmailShareDefinition);
+ helper.appendShareReplyData(_testUserShareDefinition);
+ QCOMPARE(helper.shareCount(), 3);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1403,11 +881,11 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(model.rowCount(), helper.shareCount());
QCOMPARE(model.sharees().count(), 2); // Link shares don't have sharees
@@ -1415,8 +893,8 @@ private slots:
const ShareePtr sharee(new Sharee("testsharee@nextcloud.com", "Test sharee", Sharee::Type::Email));
model.createNewUserGroupShare(sharee);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 4); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 4); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
const auto sharees = model.sharees();
QCOMPARE(sharees.count(), 3); // Link shares don't have sharees
@@ -1428,7 +906,7 @@ private slots:
const auto sharePtr = shareIndex.data(ShareModel::ShareRole).value<SharePtr>();
model.deleteShare(sharePtr);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Now check the sharee is gone
QCOMPARE(model.sharees().count(), 2);
@@ -1436,13 +914,14 @@ private slots:
void testSharePropertySetError()
{
- resetTestData();
+ helper.resetTestData();
// Serve a broken share definition from the server to force an error
auto brokenLinkShareDefinition = _testLinkShareDefinition;
brokenLinkShareDefinition.shareId = QString();
- appendShareReplyData(brokenLinkShareDefinition);
+ helper.appendShareReplyData(brokenLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
ShareModel model;
QAbstractItemModelTester modelTester(&model);
@@ -1450,16 +929,17 @@ private slots:
QSignalSpy sharesChanged(&model, &ShareModel::sharesChanged);
- model.setAccountState(_accountState.data());
- model.setLocalPath(_fakeFolder.localPath() + testFileName);
+ model.setAccountState(helper.accountState.data());
+ model.setLocalPath(helper.fakeFolder.localPath() + helper.testFileName);
QVERIFY(sharesChanged.wait(5000));
- QCOMPARE(_sharesReplyData.count(), 1); // Check our test is working!
- QCOMPARE(model.rowCount(), _sharesReplyData.count());
+ QCOMPARE(helper.shareCount(), 1); // Check our test is working!
+ QCOMPARE(model.rowCount(), helper.shareCount());
// Reset the fake server to pretend like nothing is wrong there
- _sharesReplyData = QJsonArray();
- appendShareReplyData(_testLinkShareDefinition);
+ helper.resetTestShares();
+ helper.appendShareReplyData(_testLinkShareDefinition);
+ QCOMPARE(helper.shareCount(), 1);
// Now try changing a property of the share
const auto shareIndex = model.index(model.rowCount() - 1, 0, {});