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-21 15:45:00 +0300
committerClaudio Cambra <claudio.cambra@nextcloud.com>2022-11-10 15:23:10 +0300
commitcf47820282b27928b760df0fc475d632eb2184c4 (patch)
tree563238e39aac82a9c8cf7294c82387ccc2d1c187
parent4ff739d4aa222a1af9423337288b9550d5de6340 (diff)
Add an end to end test utils file
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
-rw-r--r--src/gui/folderman.h2
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/endtoendtestutils.cpp174
-rw-r--r--test/endtoendtestutils.h98
4 files changed, 275 insertions, 0 deletions
diff --git a/src/gui/folderman.h b/src/gui/folderman.h
index 6409cc8b4..8ef348548 100644
--- a/src/gui/folderman.h
+++ b/src/gui/folderman.h
@@ -29,6 +29,7 @@ class TestFolderMan;
class TestCfApiShellExtensionsIPC;
class TestShareModel;
class ShareTestHelper;
+class EndToEndTestHelper;
namespace OCC {
@@ -382,6 +383,7 @@ private:
friend class ::TestFolderMan;
friend class ::TestCfApiShellExtensionsIPC;
friend class ::ShareTestHelper;
+ friend class ::EndToEndTestHelper;
};
} // namespace OCC
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a66133905..cf6599d2b 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,6 +11,7 @@ add_library(testutils
themeutils.cpp
testhelper.cpp
sharetestutils.cpp
+ endtoendtestutils.cpp
)
target_link_libraries(testutils PUBLIC Nextcloud::sync Qt5::Test)
diff --git a/test/endtoendtestutils.cpp b/test/endtoendtestutils.cpp
new file mode 100644
index 000000000..a25a7e145
--- /dev/null
+++ b/test/endtoendtestutils.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 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 "endtoendtestutils.h"
+
+#include <QNetworkProxy>
+#include <QJsonObject>
+#include <QSignalSpy>
+
+#include "cmd/simplesslerrorhandler.h"
+#include "creds/httpcredentials.h"
+#include "gui/accountmanager.h"
+#include "libsync/theme.h"
+#include "accessmanager.h"
+#include "httplogger.h"
+#include "syncenginetestutils.h"
+#include "testhelper.h"
+
+constexpr auto serverUrl = "https://server";
+
+Q_LOGGING_CATEGORY(lcEndToEndTestUtils, "nextcloud.gui.endtoendtestutils", QtInfoMsg)
+
+/** End to end test credentials access manager class **/
+
+class EndToEndTestCredentialsAccessManager : public OCC::AccessManager
+{
+public:
+ EndToEndTestCredentialsAccessManager(const EndToEndTestCredentials *cred, QObject *parent = nullptr)
+ : OCC::AccessManager(parent)
+ , _cred(cred)
+ {
+ }
+
+protected:
+ QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) override
+ {
+ if(!_cred) {
+ qCWarning(lcEndToEndTestUtils) << "Could not create request -- null creds!";
+ return {};
+ }
+
+ QNetworkRequest req(request);
+ QByteArray credHash = QByteArray(_cred->user().toUtf8() + ":" + _cred->password().toUtf8()).toBase64();
+ req.setRawHeader("Authorization", "Basic " + credHash);
+
+ return OCC::AccessManager::createRequest(op, req, outgoingData);
+ }
+
+private:
+ // The credentials object dies along with the account, while the QNAM might
+ // outlive both.
+ QPointer<const EndToEndTestCredentials> _cred;
+};
+
+/** End to end test credentials class **/
+
+QNetworkAccessManager *EndToEndTestCredentials::createQNAM() const
+{
+ return new EndToEndTestCredentialsAccessManager(this);
+}
+
+/** End to end test helper class **/
+
+EndToEndTestHelper::~EndToEndTestHelper()
+{
+ removeConfiguredSyncFolder();
+ removeConfiguredAccount();
+
+ OCC::AccountManager::instance()->shutdown();
+}
+
+void EndToEndTestHelper::startAccountConfig()
+{
+ const auto accountManager = OCC::AccountManager::instance();
+ _account = accountManager->createAccount();
+
+ _account->setCredentials(new EndToEndTestCredentials);
+ _account->setUrl(OCC::Theme::instance()->overrideServerUrl());
+
+ const auto serverUrlString = QString(serverUrl);
+ _account->setUrl(serverUrlString);
+
+ _account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::NoProxy));
+ _account->setSslConfiguration(QSslConfiguration::defaultConfiguration());
+ _account->setSslErrorHandler(new OCC::SimpleSslErrorHandler);
+ _account->setTrustCertificates(true);
+
+ slotConnectToNCUrl(serverUrlString);
+}
+
+void EndToEndTestHelper::slotConnectToNCUrl(const QString &url)
+{
+ qCDebug(lcEndToEndTestUtils) << "Connect to url: " << url;
+
+ const auto fetchUserNameJob = new OCC::JsonApiJob(_account->sharedFromThis(), QStringLiteral("/ocs/v1.php/cloud/user"));
+ connect(fetchUserNameJob, &OCC::JsonApiJob::jsonReceived, this, [this, url](const QJsonDocument &json, const int statusCode) {
+ if (statusCode != 100) {
+ qCDebug(lcEndToEndTestUtils) << "Could not fetch username.";
+ }
+
+ const auto objData = json.object().value("ocs").toObject().value("data").toObject();
+ const auto userId = objData.value("id").toString("");
+ const auto displayName = objData.value("display-name").toString("");
+ _account->setDavUser(userId);
+ _account->setDavDisplayName(displayName);
+
+ _accountState = new OCC::AccountState(_account);
+
+ emit accountReady(_account);
+ });
+ fetchUserNameJob->start();
+}
+
+void EndToEndTestHelper::removeConfiguredAccount()
+{
+ OCC::AccountManager::instance()->deleteAccount(_accountState.data());
+}
+
+OCC::Folder *EndToEndTestHelper::configureSyncFolder(const QString &targetPath)
+{
+ if(_syncFolder) {
+ removeConfiguredSyncFolder();
+ }
+
+ qCDebug(lcEndToEndTestUtils) << "Creating temp end-to-end test folder.";
+ Q_ASSERT(_tempDir.isValid());
+ OCC::FileSystem::setFolderMinimumPermissions(_tempDir.path());
+ qCDebug(lcEndToEndTestUtils) << "Created temp end-to-end test folder at:" << _tempDir.path();
+
+ setupFolderMan();
+
+ OCC::FolderDefinition definition;
+ definition.localPath = _tempDir.path();
+ definition.targetPath = targetPath;
+ _syncFolder = _folderMan->addFolder(_accountState.data(), definition);
+
+ return _syncFolder;
+}
+
+void EndToEndTestHelper::removeConfiguredSyncFolder()
+{
+ if(!_syncFolder || !_folderMan) {
+ return;
+ }
+
+ QSignalSpy folderSyncFinished(_syncFolder, &OCC::Folder::syncFinished);
+ _folderMan->forceSyncForFolder(_syncFolder);
+ Q_ASSERT(folderSyncFinished.wait(3000));
+ _folderMan->unloadAndDeleteAllFolders();
+ _syncFolder = nullptr;
+}
+
+void EndToEndTestHelper::setupFolderMan()
+{
+ if(_folderMan) {
+ return;
+ }
+
+ auto folderMan = new OCC::FolderMan;
+ Q_ASSERT(folderMan);
+ folderMan->setSyncEnabled(true);
+ _folderMan.reset(folderMan);
+}
diff --git a/test/endtoendtestutils.h b/test/endtoendtestutils.h
new file mode 100644
index 000000000..c1a48329a
--- /dev/null
+++ b/test/endtoendtestutils.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 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 <QTemporaryDir>
+
+#include "gui/accountstate.h"
+#include "gui/folderman.h"
+#include "libsync/account.h"
+
+constexpr auto testUsername = "test";
+constexpr auto testPassword = "test";
+
+class QNetworkReply;
+
+namespace OCC
+{
+class Folder;
+class FolderMan;
+}
+
+class EndToEndTestCredentials : public OCC::AbstractCredentials
+{
+ Q_OBJECT
+
+public:
+ explicit EndToEndTestCredentials()
+ : OCC::AbstractCredentials()
+ , _user(testUsername)
+ , _password(testPassword)
+ {
+ _wasFetched = true;
+ };
+
+ [[nodiscard]] QString authType() const override { return QStringLiteral("http"); }
+ [[nodiscard]] QString user() const override { return _user; }
+ [[nodiscard]] QString password() const override { return _password; }
+ [[nodiscard]] bool ready() const override { return true; }
+ bool stillValid(QNetworkReply *) override { return true; }
+ void askFromUser() override {};
+ void fetchFromKeychain() override { _wasFetched = true; Q_EMIT fetched(); };
+ void persist() override {};
+ void invalidateToken() override {};
+ void forgetSensitiveData() override {};
+
+ [[nodiscard]] QNetworkAccessManager *createQNAM() const override;
+
+private:
+ QString _user;
+ QString _password;
+};
+
+class EndToEndTestHelper : public QObject
+{
+ Q_OBJECT
+
+public:
+ EndToEndTestHelper() = default;
+ ~EndToEndTestHelper() override;
+
+ [[nodiscard]] OCC::AccountPtr account() const { return _account; }
+ [[nodiscard]] OCC::AccountStatePtr accountState() const { return _accountState; }
+
+ OCC::Folder *configureSyncFolder(const QString &targetPath = QStringLiteral(""));
+
+signals:
+ void accountReady(const OCC::AccountPtr &account);
+
+public slots:
+ void startAccountConfig();
+ void removeConfiguredAccount();
+ void removeConfiguredSyncFolder();
+
+private slots:
+ void slotConnectToNCUrl(const QString &url);
+ void setupFolderMan();
+
+private:
+ OCC::AccountPtr _account;
+ OCC::AccountStatePtr _accountState;
+ QScopedPointer<OCC::FolderMan> _folderMan;
+ QTemporaryDir _tempDir;
+
+ OCC::Folder* _syncFolder = nullptr;
+};