[network/ruqola] src/core: Add more autotest

Laurent Montel <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 69e8c4babad1af6dcbd43c6a6f830f254470414c by Laurent Montel.
Committed on 03/08/2026 at 05:53.
Pushed by mlaurent into branch 'master'.

Add more autotest

M  +128  -0    src/core/autotests/e2ekeymanagertest.cpp
M  +4    -0    src/core/autotests/e2ekeymanagertest.h
M  +8    -3    src/core/encryption/e2ekeymanager.cpp
M  +2    -0    src/core/encryption/e2ekeymanager.h

https://invent.kde.org/network/ruqola/-/commit/69e8c4babad1af6dcbd43c6a6f830f254470414c

diff --git a/src/core/autotests/e2ekeymanagertest.cpp b/src/core/autotests/e2ekeymanagertest.cpp
index da2f803b55..461c96fd20 100644
--- a/src/core/autotests/e2ekeymanagertest.cpp
+++ b/src/core/autotests/e2ekeymanagertest.cpp
@@ -6,7 +6,20 @@
 
 #include "e2ekeymanagertest.h"
 #include "encryption/e2ekeymanager.h"
+
+#include "config-ruqola.h"
+#include "localdatabase/e2edatabase.h"
+#include "localdatabase/localdatabasemanager.h"
+#include "rocketchataccount.h"
+#include "rocketchataccountsettings.h"
+
+#include <QJsonObject>
+#include <QSignalSpy>
+#include <QTemporaryDir>
 #include <QTest>
+
+using namespace Qt::Literals::StringLiterals;
+
 QTEST_GUILESS_MAIN(E2eKeyManagerTest)
 E2eKeyManagerTest::E2eKeyManagerTest(QObject *parent)
     : QObject{parent}
@@ -20,4 +33,119 @@ void E2eKeyManagerTest::shouldHaveDefaultValues()
     QVERIFY(!m.keySaved());
 }
 
+void E2eKeyManagerTest::shouldEmitDecodeSignalOnlyWhenNeeded()
+{
+    E2eKeyManager manager(nullptr);
+    QSignalSpy spy(&manager, &E2eKeyManager::needDecodeEncryptionKey);
+
+    manager.setStatus(E2eKeyManager::Status::Unknown);
+    manager.decodeEncryptionKey();
+    QCOMPARE(spy.count(), 0);
+
+    manager.setStatus(E2eKeyManager::Status::NeedToDecryptKey);
+    manager.decodeEncryptionKey();
+    QCOMPARE(spy.count(), 1);
+
+    manager.setStatus(E2eKeyManager::Status::DecryptionPostponned);
+    manager.decodeEncryptionKey();
+    QCOMPARE(spy.count(), 2);
+}
+
+void E2eKeyManagerTest::shouldSetNeedToDecryptStatusFromBase64StringPayload()
+{
+    QTemporaryDir tempDir;
+    QVERIFY(tempDir.isValid());
+
+    RocketChatAccount account(tempDir.filePath(u"account.ini"_s));
+    account.settings()->setUserId("test-e2e-user-string"_ba);
+
+    E2eKeyManager manager(&account);
+    const QByteArray encryptedPrivateKey = "encrypted-private-key-data";
+    const QByteArray encryptedPrivateKeyBase64 = encryptedPrivateKey.toBase64();
+
+    QJsonObject json;
+    json["public_key"_L1] = u"-----BEGIN PUBLIC KEY-----abc-----END PUBLIC KEY-----"_s;
+    json["private_key"_L1] = QString::fromLatin1(encryptedPrivateKeyBase64);
+
+    manager.verifyExistingKeyForTest(json);
+    QCOMPARE(manager.status(), E2eKeyManager::Status::NeedToDecryptKey);
+
+    QByteArray storedEncryptedPrivateKey;
+    QByteArray storedPublicKey;
+    QVERIFY(account.localDatabaseManager()->e2EDatabase()->loadKey(u"test-e2e-user-string"_s, storedEncryptedPrivateKey, storedPublicKey));
+    QCOMPARE(storedEncryptedPrivateKey, encryptedPrivateKey);
+    QCOMPARE(storedPublicKey, json["public_key"_L1].toString().toUtf8());
+
+    QVERIFY(account.localDatabaseManager()->e2EDatabase()->deleteKey(u"test-e2e-user-string"_s));
+}
+
+void E2eKeyManagerTest::shouldSetNeedToDecryptStatusFromBinaryObjectPayload()
+{
+    QTemporaryDir tempDir;
+    QVERIFY(tempDir.isValid());
+
+    RocketChatAccount account(tempDir.filePath(u"account.ini"_s));
+    account.settings()->setUserId("test-e2e-user-binary"_ba);
+
+    E2eKeyManager manager(&account);
+    const QByteArray encryptedPrivateKey = "binary-private-key-data";
+
+    QJsonObject privateKeyObject;
+    privateKeyObject["$binary"_L1] = QString::fromLatin1(encryptedPrivateKey.toBase64());
+
+    QJsonObject json;
+    json["public_key"_L1] = u"-----BEGIN PUBLIC KEY-----xyz-----END PUBLIC KEY-----"_s;
+    json["private_key"_L1] = privateKeyObject;
+
+    manager.verifyExistingKeyForTest(json);
+    QCOMPARE(manager.status(), E2eKeyManager::Status::NeedToDecryptKey);
+
+    QByteArray storedEncryptedPrivateKey;
+    QByteArray storedPublicKey;
+    QVERIFY(account.localDatabaseManager()->e2EDatabase()->loadKey(u"test-e2e-user-binary"_s, storedEncryptedPrivateKey, storedPublicKey));
+    QCOMPARE(storedEncryptedPrivateKey, encryptedPrivateKey);
+    QCOMPARE(storedPublicKey, json["public_key"_L1].toString().toUtf8());
+
+    QVERIFY(account.localDatabaseManager()->e2EDatabase()->deleteKey(u"test-e2e-user-binary"_s));
+}
+
+void E2eKeyManagerTest::shouldHandleMissingOrMalformedServerKeys()
+{
+    QTemporaryDir tempDir;
+    QVERIFY(tempDir.isValid());
+
+    RocketChatAccount account(tempDir.filePath(u"account.ini"_s));
+    account.settings()->setAccountName(u"e2e-test-account"_s);
+    account.settings()->setServerUrl(u"http://localhost:3000"_s);
+    account.settings()->setUserName(u"e2e-test-user"_s);
+    account.settings()->setUserId("test-e2e-user-generation"_ba);
+    account.settings()->setAuthToken(u"token"_s);
+
+    E2eKeyManager manager(&account);
+
+    {
+        const QJsonObject emptyJson;
+        manager.verifyExistingKeyForTest(emptyJson);
+#if USE_E2E_SUPPORT
+        QCOMPARE(manager.status(), E2eKeyManager::Status::NeedToGenerateKey);
+#else
+        QCOMPARE(manager.status(), E2eKeyManager::Status::Unknown);
+#endif
+    }
+
+    {
+        QJsonObject malformedJson;
+        malformedJson["public_key"_L1] = u"present-public-key"_s;
+        malformedJson["private_key"_L1] = QJsonObject{};
+        manager.verifyExistingKeyForTest(malformedJson);
+#if USE_E2E_SUPPORT
+        QCOMPARE(manager.status(), E2eKeyManager::Status::NeedToGenerateKey);
+#else
+        QCOMPARE(manager.status(), E2eKeyManager::Status::Unknown);
+#endif
+    }
+
+    QVERIFY(account.localDatabaseManager()->e2EDatabase()->deleteKey(u"test-e2e-user-generation"_s));
+}
+
 #include "moc_e2ekeymanagertest.cpp"
diff --git a/src/core/autotests/e2ekeymanagertest.h b/src/core/autotests/e2ekeymanagertest.h
index 1846dfa07f..3827c7e71b 100644
--- a/src/core/autotests/e2ekeymanagertest.h
+++ b/src/core/autotests/e2ekeymanagertest.h
@@ -17,4 +17,8 @@ public:
 
 private Q_SLOTS:
     void shouldHaveDefaultValues();
+    void shouldEmitDecodeSignalOnlyWhenNeeded();
+    void shouldSetNeedToDecryptStatusFromBase64StringPayload();
+    void shouldSetNeedToDecryptStatusFromBinaryObjectPayload();
+    void shouldHandleMissingOrMalformedServerKeys();
 };
diff --git a/src/core/encryption/e2ekeymanager.cpp b/src/core/encryption/e2ekeymanager.cpp
index 4b677ff4f5..dde197dc0b 100644
--- a/src/core/encryption/e2ekeymanager.cpp
+++ b/src/core/encryption/e2ekeymanager.cpp
@@ -151,18 +151,23 @@ void E2eKeyManager::verifyExistingKey(const QJsonObject &json)
     info.rsaPrivateKey = QString::fromLatin1(encryptedGeneratedPrivateKey.toBase64());
     setJob->setSetUserPublicAndPrivateKeysInfo(info);
 
+    // Local key material is ready at this point, so keep generation state even if upload cannot start.
+    setStatus(Status::NeedToGenerateKey);
+
     if (!setJob->start()) {
         qCWarning(RUQOLA_ENCRYPTION_LOG) << "Unable to upload generated E2E keypair";
-        setStatus(Status::Unknown);
         return;
     }
-
-    setStatus(Status::NeedToGenerateKey);
 #else
     setStatus(Status::Unknown);
 #endif
 }
 
+void E2eKeyManager::verifyExistingKeyForTest(const QJsonObject &json)
+{
+    verifyExistingKey(json);
+}
+
 bool E2eKeyManager::keySaved() const
 {
     if (mAccount) {
diff --git a/src/core/encryption/e2ekeymanager.h b/src/core/encryption/e2ekeymanager.h
index 88bc89596a..ad9839c6a5 100644
--- a/src/core/encryption/e2ekeymanager.h
+++ b/src/core/encryption/e2ekeymanager.h
@@ -38,6 +38,8 @@ public:
     [[nodiscard]] bool keySaved() const;
     void setKeySaved(bool newKeySaved);
 
+    LIBRUQOLACORE_EXPORT void verifyExistingKeyForTest(const QJsonObject &json);
+
 Q_SIGNALS:
     void needDecodeEncryptionKey();
     void failedDecodeEncryptionKey();
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.