Kaynağa Gözat

Refactor push notification test utils

Signed-off-by: Felix Weilbach <felix.weilbach@nextcloud.com>
Felix Weilbach 4 yıl önce
ebeveyn
işleme
d7499b0746

+ 79 - 7
test/pushnotificationstestutils.cpp

@@ -1,8 +1,10 @@
 #include <QLoggingCategory>
 #include <QSignalSpy>
 #include <QTest>
+#include <functional>
 
 #include "pushnotificationstestutils.h"
+#include "pushnotifications.h"
 
 Q_LOGGING_CATEGORY(lcFakeWebSocketServer, "nextcloud.test.fakewebserver", QtInfoMsg)
 
@@ -10,13 +12,13 @@ FakeWebSocketServer::FakeWebSocketServer(quint16 port, QObject *parent)
     : QObject(parent)
     , _webSocketServer(new QWebSocketServer(QStringLiteral("Fake Server"), QWebSocketServer::NonSecureMode, this))
 {
-    if (_webSocketServer->listen(QHostAddress::Any, port)) {
-        connect(_webSocketServer, &QWebSocketServer::newConnection, this, &FakeWebSocketServer::onNewConnection);
-        connect(_webSocketServer, &QWebSocketServer::closed, this, &FakeWebSocketServer::closed);
-        qCInfo(lcFakeWebSocketServer) << "Open fake websocket server on port:" << port;
-        return;
+    if (!_webSocketServer->listen(QHostAddress::Any, port)) {
+        Q_UNREACHABLE();
     }
-    Q_UNREACHABLE();
+    connect(_webSocketServer, &QWebSocketServer::newConnection, this, &FakeWebSocketServer::onNewConnection);
+    connect(_webSocketServer, &QWebSocketServer::closed, this, &FakeWebSocketServer::closed);
+    qCInfo(lcFakeWebSocketServer) << "Open fake websocket server on port:" << port;
+    _processTextMessageSpy = std::make_unique<QSignalSpy>(this, &FakeWebSocketServer::processTextMessage);
 }
 
 FakeWebSocketServer::~FakeWebSocketServer()
@@ -24,6 +26,46 @@ FakeWebSocketServer::~FakeWebSocketServer()
     close();
 }
 
+QWebSocket *FakeWebSocketServer::authenticateAccount(const OCC::AccountPtr account, std::function<void(OCC::PushNotifications *pushNotifications)> beforeAuthentication, std::function<void(void)> afterAuthentication)
+{
+    const auto pushNotifications = account->pushNotifications();
+    Q_ASSERT(pushNotifications);
+    QSignalSpy readySpy(pushNotifications, &OCC::PushNotifications::ready);
+
+    beforeAuthentication(pushNotifications);
+
+    // Wait for authentication
+    if (!waitForTextMessages()) {
+        return nullptr;
+    }
+
+    // Right authentication data should be sent
+    if (textMessagesCount() != 2) {
+        return nullptr;
+    }
+
+    const auto socket = socketForTextMessage(0);
+    const auto userSent = textMessage(0);
+    const auto passwordSent = textMessage(1);
+
+    if (userSent != account->credentials()->user() || passwordSent != account->credentials()->password()) {
+        return nullptr;
+    }
+
+    // Sent authenticated
+    socket->sendTextMessage("authenticated");
+
+    // Wait for ready signal
+    readySpy.wait();
+    if (readySpy.count() != 1 || !account->pushNotifications()->isReady()) {
+        return nullptr;
+    }
+
+    afterAuthentication();
+
+    return socket;
+}
+
 void FakeWebSocketServer::close()
 {
     if (_webSocketServer->isListening()) {
@@ -64,7 +106,34 @@ void FakeWebSocketServer::socketDisconnected()
     }
 }
 
-OCC::AccountPtr FakeWebSocketServer::createAccount()
+bool FakeWebSocketServer::waitForTextMessages() const
+{
+    return _processTextMessageSpy->wait();
+}
+
+uint32_t FakeWebSocketServer::textMessagesCount() const
+{
+    return _processTextMessageSpy->count();
+}
+
+QString FakeWebSocketServer::textMessage(uint32_t messageNumber) const
+{
+    Q_ASSERT(messageNumber < _processTextMessageSpy->count());
+    return _processTextMessageSpy->at(messageNumber).at(1).toString();
+}
+
+QWebSocket *FakeWebSocketServer::socketForTextMessage(uint32_t messageNumber) const
+{
+    Q_ASSERT(messageNumber < _processTextMessageSpy->count());
+    return _processTextMessageSpy->at(messageNumber).at(0).value<QWebSocket *>();
+}
+
+void FakeWebSocketServer::clearTextMessages()
+{
+    _processTextMessageSpy->clear();
+}
+
+OCC::AccountPtr FakeWebSocketServer::createAccount(const QString &username, const QString &password)
 {
     auto account = OCC::Account::create();
 
@@ -87,6 +156,9 @@ OCC::AccountPtr FakeWebSocketServer::createAccount()
 
     account->setCapabilities(capabilitiesMap);
 
+    auto credentials = new CredentialsStub(username, password);
+    account->setCredentials(credentials);
+
     return account;
 }
 

+ 17 - 1
test/pushnotificationstestutils.h

@@ -18,6 +18,7 @@
 
 #include <QWebSocketServer>
 #include <QWebSocket>
+#include <QSignalSpy>
 
 #include "creds/abstractcredentials.h"
 #include "account.h"
@@ -30,9 +31,22 @@ public:
 
     ~FakeWebSocketServer();
 
+    QWebSocket *authenticateAccount(
+        const OCC::AccountPtr account, std::function<void(OCC::PushNotifications *pushNotifications)> beforeAuthentication = [](OCC::PushNotifications *) {}, std::function<void(void)> afterAuthentication = [] {});
+
     void close();
 
-    static OCC::AccountPtr createAccount();
+    bool waitForTextMessages() const;
+
+    uint32_t textMessagesCount() const;
+
+    QString textMessage(uint32_t messageNumber) const;
+
+    QWebSocket *socketForTextMessage(uint32_t messageNumber) const;
+
+    void clearTextMessages();
+
+    static OCC::AccountPtr createAccount(const QString &username = "user", const QString &password = "password");
 
 signals:
     void closed();
@@ -46,6 +60,8 @@ private slots:
 private:
     QWebSocketServer *_webSocketServer;
     QList<QWebSocket *> _clients;
+
+    std::unique_ptr<QSignalSpy> _processTextMessageSpy;
 };
 
 class CredentialsStub : public OCC::AbstractCredentials

+ 70 - 192
test/testpushnotifications.cpp

@@ -3,9 +3,24 @@
 #include <QWebSocketServer>
 #include <QSignalSpy>
 
+#include "accountfwd.h"
 #include "pushnotifications.h"
 #include "pushnotificationstestutils.h"
 
+bool verifyCalledOnceWithAccount(QSignalSpy &spy, OCC::AccountPtr account)
+{
+    if (spy.count() != 1) {
+        return false;
+    }
+
+    auto accountFromSpy = spy.at(0).at(0).value<OCC::Account *>();
+    if (accountFromSpy != account.data()) {
+        return false;
+    }
+
+    return true;
+}
+
 class TestPushNotifications : public QObject
 {
     Q_OBJECT
@@ -14,170 +29,107 @@ private slots:
     void testSetup_correctCredentials_authenticateAndEmitReady()
     {
         FakeWebSocketServer fakeServer;
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-        const QString user = "user";
-        const QString password = "password";
+        std::unique_ptr<QSignalSpy> filesChangedSpy;
+        std::unique_ptr<QSignalSpy> notificationsChangedSpy;
+        std::unique_ptr<QSignalSpy> activitiesChangedSpy;
         auto account = FakeWebSocketServer::createAccount();
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
-        QSignalSpy readySpy(account->pushNotifications(), &OCC::PushNotifications::ready);
-        QVERIFY(readySpy.isValid());
-
-        // Wait for authentication
-        QVERIFY(processTextMessageSpy.wait());
-
-        // Right authentication data should be sent
-        QCOMPARE(processTextMessageSpy.count(), 2);
-
-        const auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
-        const auto userSent = processTextMessageSpy.at(0).at(1).toString();
-        const auto passwordSent = processTextMessageSpy.at(1).at(1).toString();
-
-        QCOMPARE(userSent, user);
-        QCOMPARE(passwordSent, password);
-
-        // Sent authenticated
-        socket->sendTextMessage("authenticated");
 
-        // Wait for ready signal
-        readySpy.wait();
-        QCOMPARE(readySpy.count(), 1);
-        QCOMPARE(account->pushNotifications()->isReady(), true);
+        QVERIFY(fakeServer.authenticateAccount(
+            account, [&](OCC::PushNotifications *pushNotifications) {
+                filesChangedSpy.reset(new QSignalSpy(pushNotifications, &OCC::PushNotifications::filesChanged));
+                notificationsChangedSpy.reset(new QSignalSpy(pushNotifications, &OCC::PushNotifications::notificationsChanged));
+                activitiesChangedSpy.reset(new QSignalSpy(pushNotifications, &OCC::PushNotifications::activitiesChanged));
+            },
+            [&] {
+                QVERIFY(verifyCalledOnceWithAccount(*filesChangedSpy, account));
+                QVERIFY(verifyCalledOnceWithAccount(*notificationsChangedSpy, account));
+                QVERIFY(verifyCalledOnceWithAccount(*activitiesChangedSpy, account));
+            }));
     }
 
     void testOnWebSocketTextMessageReceived_notifyFileMessage_emitFilesChanged()
     {
-        const QString user = "user";
-        const QString password = "password";
         FakeWebSocketServer fakeServer;
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-
         auto account = FakeWebSocketServer::createAccount();
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
+        const auto socket = fakeServer.authenticateAccount(account);
+        QVERIFY(socket);
         QSignalSpy filesChangedSpy(account->pushNotifications(), &OCC::PushNotifications::filesChanged);
-        QVERIFY(filesChangedSpy.isValid());
 
-        // Wait for authentication and then send notify_file push notification
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        const auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
         socket->sendTextMessage("notify_file");
 
         // filesChanged signal should be emitted
         QVERIFY(filesChangedSpy.wait());
-        QCOMPARE(filesChangedSpy.count(), 1);
-        auto accountFilesChanged = filesChangedSpy.at(0).at(0).value<OCC::Account *>();
-        QCOMPARE(accountFilesChanged, account.data());
+        QVERIFY(verifyCalledOnceWithAccount(filesChangedSpy, account));
     }
 
     void testOnWebSocketTextMessageReceived_notifyActivityMessage_emitNotification()
     {
-        const QString user = "user";
-        const QString password = "password";
         FakeWebSocketServer fakeServer;
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-
         auto account = FakeWebSocketServer::createAccount();
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
+        const auto socket = fakeServer.authenticateAccount(account);
+        QVERIFY(socket);
         QSignalSpy activitySpy(account->pushNotifications(), &OCC::PushNotifications::activitiesChanged);
         QVERIFY(activitySpy.isValid());
 
-        // Wait for authentication and then send notify_file push notification
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        const auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
+        // Send notify_file push notification
         socket->sendTextMessage("notify_activity");
 
         // notification signal should be emitted
         QVERIFY(activitySpy.wait());
-        QCOMPARE(activitySpy.count(), 1);
-        auto accountFilesChanged = activitySpy.at(0).at(0).value<OCC::Account *>();
-        QCOMPARE(accountFilesChanged, account.data());
+        QVERIFY(verifyCalledOnceWithAccount(activitySpy, account));
     }
 
     void testOnWebSocketTextMessageReceived_notifyNotificationMessage_emitNotification()
     {
-        const QString user = "user";
-        const QString password = "password";
         FakeWebSocketServer fakeServer;
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-
         auto account = FakeWebSocketServer::createAccount();
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
+        const auto socket = fakeServer.authenticateAccount(account);
+        QVERIFY(socket);
         QSignalSpy notificationSpy(account->pushNotifications(), &OCC::PushNotifications::notificationsChanged);
         QVERIFY(notificationSpy.isValid());
 
-        // Wait for authentication and then send notify_file push notification
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        const auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
+        // Send notify_file push notification
         socket->sendTextMessage("notify_notification");
 
         // notification signal should be emitted
         QVERIFY(notificationSpy.wait());
-        QCOMPARE(notificationSpy.count(), 1);
-        auto accountFilesChanged = notificationSpy.at(0).at(0).value<OCC::Account *>();
-        QCOMPARE(accountFilesChanged, account.data());
+        QVERIFY(verifyCalledOnceWithAccount(notificationSpy, account));
     }
 
     void testOnWebSocketTextMessageReceived_invalidCredentialsMessage_reconnectWebSocket()
     {
-        const QString user = "user";
-        const QString password = "password";
         FakeWebSocketServer fakeServer;
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-
         auto account = FakeWebSocketServer::createAccount();
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
         // Need to set reconnect timer interval to zero for tests
         account->pushNotifications()->setReconnectTimerInterval(0);
 
         // Wait for authentication attempt and then sent invalid credentials
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        const auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
-        const auto firstPasswordSent = processTextMessageSpy.at(1).at(1).toString();
-        QCOMPARE(firstPasswordSent, password);
-        processTextMessageSpy.clear();
+        QVERIFY(fakeServer.waitForTextMessages());
+        QCOMPARE(fakeServer.textMessagesCount(), 2);
+        const auto socket = fakeServer.socketForTextMessage(0);
+        const auto firstPasswordSent = fakeServer.textMessage(1);
+        QCOMPARE(firstPasswordSent, account->credentials()->password());
+        fakeServer.clearTextMessages();
         socket->sendTextMessage("err: Invalid credentials");
 
         // Wait for a new authentication attempt
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        const auto secondPasswordSent = processTextMessageSpy.at(1).at(1).toString();
-        QCOMPARE(secondPasswordSent, password);
+        QVERIFY(fakeServer.waitForTextMessages());
+        QCOMPARE(fakeServer.textMessagesCount(), 2);
+        const auto secondPasswordSent = fakeServer.textMessage(1);
+        QCOMPARE(secondPasswordSent, account->credentials()->password());
     }
 
     void testOnWebSocketError_connectionLost_emitConnectionLost()
     {
-        const QString user = "user";
-        const QString password = "password";
         FakeWebSocketServer fakeServer;
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-
         auto account = FakeWebSocketServer::createAccount();
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
-        // Need to set reconnect timer interval to zero for tests
-        account->pushNotifications()->setReconnectTimerInterval(0);
-
         QSignalSpy connectionLostSpy(account->pushNotifications(), &OCC::PushNotifications::connectionLost);
         QVERIFY(connectionLostSpy.isValid());
 
         // Wait for authentication and then sent a network error
-        processTextMessageSpy.wait();
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
+        QVERIFY(fakeServer.waitForTextMessages());
+        QCOMPARE(fakeServer.textMessagesCount(), 2);
+        auto socket = fakeServer.socketForTextMessage(0);
         socket->abort();
 
         QVERIFY(connectionLostSpy.wait());
@@ -187,57 +139,34 @@ private slots:
 
     void testSetup_maxConnectionAttemptsReached_deletePushNotifications()
     {
-        const QString user = "user";
-        const QString password = "password";
         FakeWebSocketServer fakeServer;
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-
         auto account = FakeWebSocketServer::createAccount();
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
         account->pushNotifications()->setReconnectTimerInterval(0);
         QSignalSpy authenticationFailedSpy(account->pushNotifications(), &OCC::PushNotifications::authenticationFailed);
         QVERIFY(authenticationFailedSpy.isValid());
 
         // Let three authentication attempts fail
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
-        socket->sendTextMessage("err: Invalid credentials");
-
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 4);
-        socket = processTextMessageSpy.at(2).at(0).value<QWebSocket *>();
-        socket->sendTextMessage("err: Invalid credentials");
-
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 6);
-        socket = processTextMessageSpy.at(4).at(0).value<QWebSocket *>();
-        socket->sendTextMessage("err: Invalid credentials");
+        for (uint8_t i = 0; i < 3; ++i) {
+            QVERIFY(fakeServer.waitForTextMessages());
+            QCOMPARE(fakeServer.textMessagesCount(), 2);
+            auto socket = fakeServer.socketForTextMessage(0);
+            fakeServer.clearTextMessages();
+            socket->sendTextMessage("err: Invalid credentials");
+        }
 
         // Now the authenticationFailed Signal should be emitted
         QVERIFY(authenticationFailedSpy.wait());
         QCOMPARE(authenticationFailedSpy.count(), 1);
-
         // Account deleted the push notifications
         QCOMPARE(account->pushNotifications(), nullptr);
     }
 
     void testOnWebSocketSslError_sslError_deletePushNotifications()
     {
-        const QString user = "user";
-        const QString password = "password";
         FakeWebSocketServer fakeServer;
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-
         auto account = FakeWebSocketServer::createAccount();
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
-
-        processTextMessageSpy.wait();
 
+        QVERIFY(fakeServer.waitForTextMessages());
         // FIXME: This a little bit ugly but I had no better idea how to trigger a error on the websocket client.
         // The websocket that is retrived through the server is not connected to the ssl error signal.
         auto pushNotificationsWebSocketChildren = account->pushNotifications()->findChildren<QWebSocket *>();
@@ -248,45 +177,14 @@ private slots:
         QCOMPARE(account->pushNotifications(), nullptr);
     }
 
-    void testAccountSetCredentials_correctCredentials_emitPushNotificationsReady()
-    {
-        FakeWebSocketServer fakeServer;
-        auto account = FakeWebSocketServer::createAccount();
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-        const QString user = "user";
-        const QString password = "password";
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
-
-        QSignalSpy pushNotificationsReady(account.data(), &OCC::Account::pushNotificationsReady);
-        QVERIFY(pushNotificationsReady.isValid());
-
-        // Wait for authentication
-        QVERIFY(processTextMessageSpy.wait());
-        auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
-        // Don't care about which message was sent
-        socket->sendTextMessage("authenticated");
-
-        // Wait for push notifactions ready signal
-        QVERIFY(pushNotificationsReady.wait());
-        auto accountSent = pushNotificationsReady.at(0).at(0).value<OCC::Account *>();
-        QCOMPARE(accountSent, account.data());
-    }
-
     void testAccount_web_socket_connectionLost_emitNotificationsDisabled()
     {
         FakeWebSocketServer fakeServer;
         auto account = FakeWebSocketServer::createAccount();
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-        const QString user = "user";
-        const QString password = "password";
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
-
         // Need to set reconnect timer interval to zero for tests
         account->pushNotifications()->setReconnectTimerInterval(0);
+        const auto socket = fakeServer.authenticateAccount(account);
+        QVERIFY(socket);
 
         QSignalSpy connectionLostSpy(account->pushNotifications(), &OCC::PushNotifications::connectionLost);
         QVERIFY(connectionLostSpy.isValid());
@@ -295,9 +193,6 @@ private slots:
         QVERIFY(pushNotificationsDisabledSpy.isValid());
 
         // Wait for authentication and then sent a network error
-        processTextMessageSpy.wait();
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
         socket->abort();
 
         QVERIFY(pushNotificationsDisabledSpy.wait());
@@ -313,42 +208,25 @@ private slots:
     {
         FakeWebSocketServer fakeServer;
         auto account = FakeWebSocketServer::createAccount();
-        QSignalSpy processTextMessageSpy(&fakeServer, &FakeWebSocketServer::processTextMessage);
-        QVERIFY(processTextMessageSpy.isValid());
-        const QString user = "user";
-        const QString password = "password";
-        auto credentials = new CredentialsStub(user, password);
-        account->setCredentials(credentials);
-
         account->pushNotifications()->setReconnectTimerInterval(0);
         QSignalSpy authenticationFailedSpy(account->pushNotifications(), &OCC::PushNotifications::authenticationFailed);
         QVERIFY(authenticationFailedSpy.isValid());
-
         QSignalSpy pushNotificationsDisabledSpy(account.data(), &OCC::Account::pushNotificationsDisabled);
         QVERIFY(pushNotificationsDisabledSpy.isValid());
 
         // Let three authentication attempts fail
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 2);
-        auto socket = processTextMessageSpy.at(0).at(0).value<QWebSocket *>();
-        socket->sendTextMessage("err: Invalid credentials");
-
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 4);
-        socket = processTextMessageSpy.at(2).at(0).value<QWebSocket *>();
-        socket->sendTextMessage("err: Invalid credentials");
-
-        QVERIFY(processTextMessageSpy.wait());
-        QCOMPARE(processTextMessageSpy.count(), 6);
-        socket = processTextMessageSpy.at(4).at(0).value<QWebSocket *>();
-        socket->sendTextMessage("err: Invalid credentials");
+        for (uint8_t i = 0; i < 3; ++i) {
+            QVERIFY(fakeServer.waitForTextMessages());
+            QCOMPARE(fakeServer.textMessagesCount(), 2);
+            auto socket = fakeServer.socketForTextMessage(0);
+            fakeServer.clearTextMessages();
+            socket->sendTextMessage("err: Invalid credentials");
+        }
 
         // Now the authenticationFailed and pushNotificationsDisabled Signals should be emitted
         QVERIFY(pushNotificationsDisabledSpy.wait());
         QCOMPARE(pushNotificationsDisabledSpy.count(), 1);
-
         QCOMPARE(authenticationFailedSpy.count(), 1);
-
         auto accountSent = pushNotificationsDisabledSpy.at(0).at(0).value<OCC::Account *>();
         QCOMPARE(accountSent, account.data());
     }