Files
nextcloud-desktop/test/testclientstatusreporting.cpp
Andy Scherzinger 49038ade94 docs(reuse): Migrate to SPDX header
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
2025-04-25 17:27:21 +02:00

143 lines
6.3 KiB
C++

/*
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "account.h"
#include "accountstate.h"
#include "clientstatusreportingcommon.h"
#include "clientstatusreportingdatabase.h"
#include "clientstatusreportingnetwork.h"
#include "syncenginetestutils.h"
#include <QSignalSpy>
#include <QTest>
namespace {
static QByteArray fake200Response = R"({"ocs":{"meta":{"status":"success","statuscode":200},"data":[]}})";
}
class TestClientStatusReporting : public QObject
{
Q_OBJECT
public:
TestClientStatusReporting() = default;
QScopedPointer<FakeQNAM> fakeQnam;
OCC::Account *account;
QScopedPointer<OCC::AccountState> accountState;
QString dbFilePath;
QVariantMap bodyReceivedAndParsed;
private slots:
void initTestCase()
{
OCC::Logger::instance()->setLogFlush(true);
OCC::Logger::instance()->setLogDebug(true);
QStandardPaths::setTestModeEnabled(true);
OCC::ClientStatusReportingNetwork::clientStatusReportingTrySendTimerInterval = 1000;
OCC::ClientStatusReportingNetwork::repordSendIntervalMs = 2000;
fakeQnam.reset(new FakeQNAM({}));
account = OCC::Account::create().get();
account->setCredentials(new FakeCredentials{fakeQnam.data()});
account->setUrl(QUrl(("http://example.de")));
accountState.reset(new OCC::AccountState(account->sharedFromThis()));
const auto databaseId = QStringLiteral("%1@%2").arg(account->davUser(), account->url().toString());
const auto databaseIdHash = QCryptographicHash::hash(databaseId.toUtf8(), QCryptographicHash::Md5);
dbFilePath = QDir::tempPath() + QStringLiteral("/.tests_userdata_%1.db").arg(QString::fromLatin1(databaseIdHash.left(6).toHex()));
QFile(dbFilePath).remove();
OCC::ClientStatusReportingDatabase::dbPathForTesting = dbFilePath;
QVariantMap capabilities;
capabilities[QStringLiteral("security_guard")] = QVariantMap{
{ QStringLiteral("diagnostics"), true }
};
account->setCapabilities(capabilities);
fakeQnam->setOverride([this](QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *device) {
QNetworkReply *reply = nullptr;
const auto reqBody = device->readAll();
bodyReceivedAndParsed = QJsonDocument::fromJson(reqBody).toVariant().toMap();
reply = new FakePayloadReply(op, req, fake200Response, fakeQnam.data());
return reply;
});
}
void testReportAndSendStatuses()
{
for (int i = 0; i < 2; ++i) {
// 2 conflicts
account->reportClientStatus(OCC::ClientStatusReportingStatus::DownloadError_ConflictInvalidCharacters);
account->reportClientStatus(OCC::ClientStatusReportingStatus::DownloadError_ConflictCaseClash);
// 3 problems
account->reportClientStatus(OCC::ClientStatusReportingStatus::UploadError_ServerError);
account->reportClientStatus(OCC::ClientStatusReportingStatus::DownloadError_ServerError);
account->reportClientStatus(OCC::ClientStatusReportingStatus::DownloadError_Virtual_File_Hydration_Failure);
// 3 occurances of case ClientStatusReportingStatus::UploadError_No_Write_Permissions
account->reportClientStatus(OCC::ClientStatusReportingStatus::DownloadError_Virtual_File_Hydration_Failure);
account->reportClientStatus(OCC::ClientStatusReportingStatus::DownloadError_Virtual_File_Hydration_Failure);
// 2 occurances of E2EeError_GeneralError
account->reportClientStatus(OCC::ClientStatusReportingStatus::E2EeError_GeneralError);
account->reportClientStatus(OCC::ClientStatusReportingStatus::E2EeError_GeneralError);
// 3 occurances of case ClientStatusReportingStatus::UploadError_Virus_Detected
account->reportClientStatus(OCC::ClientStatusReportingStatus::UploadError_Virus_Detected);
account->reportClientStatus(OCC::ClientStatusReportingStatus::UploadError_Virus_Detected);
account->reportClientStatus(OCC::ClientStatusReportingStatus::UploadError_Virus_Detected);
QTest::qWait(OCC::ClientStatusReportingNetwork::clientStatusReportingTrySendTimerInterval + OCC::ClientStatusReportingNetwork::repordSendIntervalMs);
QVERIFY(!bodyReceivedAndParsed.isEmpty());
// we must have 3 virus_detected category statuses
const auto virusDetectedErrorsReceived = bodyReceivedAndParsed.value("virus_detected").toMap();
QVERIFY(!virusDetectedErrorsReceived.isEmpty());
QCOMPARE(virusDetectedErrorsReceived.value("count"), 3);
// we must have 2 e2ee errors
const auto e2eeErrorsReceived = bodyReceivedAndParsed.value("e2ee_errors").toMap();
QVERIFY(!e2eeErrorsReceived.isEmpty());
QCOMPARE(e2eeErrorsReceived.value("count"), 2);
// we must have 2 conflicts
const auto conflictsReceived = bodyReceivedAndParsed.value("sync_conflicts").toMap();
QVERIFY(!conflictsReceived.isEmpty());
QCOMPARE(conflictsReceived.value("count"), 2);
// we must have 3 problems
const auto problemsReceived = bodyReceivedAndParsed.value("problems").toMap();
QVERIFY(!problemsReceived.isEmpty());
QCOMPARE(problemsReceived.size(), 3);
const auto specificProblemMultipleOccurances = problemsReceived.value(OCC::clientStatusstatusStringFromNumber(OCC::ClientStatusReportingStatus::DownloadError_Virtual_File_Hydration_Failure)).toMap();
// among those, 3 occurances of specific problem
QCOMPARE(specificProblemMultipleOccurances.value("count"), 3);
bodyReceivedAndParsed.clear();
}
}
void testNothingReportedAndNothingSent()
{
QTest::qWait(OCC::ClientStatusReportingNetwork::clientStatusReportingTrySendTimerInterval + OCC::ClientStatusReportingNetwork::repordSendIntervalMs);
QVERIFY(bodyReceivedAndParsed.isEmpty());
}
void cleanupTestCase()
{
accountState.reset(nullptr);
delete account;
QFile(dbFilePath).remove();
}
};
QTEST_MAIN(TestClientStatusReporting)
#include "testclientstatusreporting.moc"