File indexing completed on 2024-05-19 04:45:14

0001 /*
0002     SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include <KUnifiedPush/Connector>
0007 
0008 #include "../src/distributor/distributor.h"
0009 #include "../src/distributor/message.h"
0010 #include "../src/distributor/mockpushprovider.h"
0011 
0012 #include <QDBusConnection>
0013 #include <QLoggingCategory>
0014 #include <QSettings>
0015 #include <QSignalSpy>
0016 #include <QStandardPaths>
0017 #include <QTest>
0018 
0019 class ConnectorTest : public QObject
0020 {
0021     Q_OBJECT
0022 private Q_SLOTS:
0023     void initTestCase()
0024     {
0025         QStandardPaths::setTestModeEnabled(true);
0026         qputenv("UNIFIEDPUSH_DISTRIBUTOR", "mock");
0027         qRegisterMetaType<KUnifiedPush::Connector::State>();
0028 
0029         QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
0030         QCoreApplication::setOrganizationName(QStringLiteral("KDE"));
0031 
0032         QSettings settings;
0033         settings.clear();
0034         settings.setValue(QStringLiteral("PushProvider/Type"), QStringLiteral("Mock"));
0035 
0036         QLoggingCategory::setFilterRules(QStringLiteral("org.kde.kunifiedpush.*=true"));
0037     }
0038 
0039     void init()
0040     {
0041         QSettings stateSettings(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1String("/kunifiedpush-org.kde.kunifiedpush.connectortest"), QSettings::IniFormat);
0042         stateSettings.clear();
0043     }
0044 
0045     void testNoDistributor()
0046     {
0047         KUnifiedPush::Connector con(QStringLiteral("org.kde.kunifiedpush.connectortest"));
0048         QCOMPARE(con.endpoint(), QString());
0049         QCOMPARE(con.state(), KUnifiedPush::Connector::NoDistributor);
0050     }
0051 
0052     void testWithDistributor()
0053     {
0054         using namespace KUnifiedPush;
0055         std::unique_ptr<Connector> con;
0056         std::unique_ptr<QSignalSpy> stateSpy;
0057         std::unique_ptr<QSignalSpy> endpointSpy;
0058 
0059         QVERIFY(QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.kunifiedpush.connectortest")));
0060         con.reset(new Connector(QStringLiteral("org.kde.kunifiedpush.connectortest")));
0061         QCOMPARE(con->state(), KUnifiedPush::Connector::NoDistributor);
0062         stateSpy.reset(new QSignalSpy(con.get(), &Connector::stateChanged));
0063         endpointSpy.reset(new QSignalSpy(con.get(), &Connector::endpointChanged));
0064 
0065         Distributor dist;
0066         QCOMPARE(dist.status(), KUnifiedPush::DistributorStatus::Idle);
0067         QVERIFY(QDBusConnection::sessionBus().registerService(QStringLiteral("org.unifiedpush.Distributor.mock")));
0068 
0069         QVERIFY(MockPushProvider::s_instance);
0070         QVERIFY(stateSpy->wait());
0071         QCOMPARE(con->state(), KUnifiedPush::Connector::Unregistered);
0072 
0073         con->registerClient(QStringLiteral("Push notification unit test."));
0074         QCOMPARE(con->state(), KUnifiedPush::Connector::Registering);
0075         QVERIFY(stateSpy->wait());
0076         // FIXME: delayed D-Bus replies inside the same process seem not to be actually delayed, so state get messed up after this...
0077         // QCOMPARE(con.state(), KUnifiedPush::Connector::Registered);
0078         QVERIFY(endpointSpy->wait());
0079         QCOMPARE(endpointSpy->size(), 1);
0080         QCOMPARE(con->endpoint(), QLatin1String("https://localhost/push-endpoint"));
0081         QCOMPARE(dist.status(), KUnifiedPush::DistributorStatus::Connected);
0082 
0083         // connector restart does not register at the provider but uses existing state
0084         {
0085             con.reset();
0086             QTest::qWait(10); // propagate connector D-Bus tear-down
0087             con.reset(new Connector(QStringLiteral("org.kde.kunifiedpush.connectortest")));
0088             QCOMPARE(con->endpoint(), QLatin1String("https://localhost/push-endpoint"));
0089             QCOMPARE(con->state(), KUnifiedPush::Connector::Registering);
0090             stateSpy.reset(new QSignalSpy(con.get(), &Connector::stateChanged));
0091             endpointSpy.reset(new QSignalSpy(con.get(), &Connector::endpointChanged));
0092             QVERIFY(stateSpy->wait());
0093             QCOMPARE(con->state(), KUnifiedPush::Connector::Registered);
0094         }
0095 
0096         // distributor goes away and comes back
0097         QVERIFY(QDBusConnection::sessionBus().unregisterService(QStringLiteral("org.unifiedpush.Distributor.mock")));
0098         QVERIFY(stateSpy->wait());
0099         QCOMPARE(con->state(), KUnifiedPush::Connector::NoDistributor);
0100         QVERIFY(QDBusConnection::sessionBus().registerService(QStringLiteral("org.unifiedpush.Distributor.mock")));
0101         QVERIFY(stateSpy->wait());
0102         QCOMPARE(con->state(), KUnifiedPush::Connector::Registering);
0103         QVERIFY(stateSpy->wait());
0104         QCOMPARE(con->state(), KUnifiedPush::Connector::Registered);
0105         QCOMPARE(dist.status(), KUnifiedPush::DistributorStatus::Connected);
0106 
0107         // receiving a message
0108         QSignalSpy msgSpy(con.get(), &Connector::messageReceived);
0109         KUnifiedPush::Message msg;
0110         msg.clientRemoteId = QStringLiteral("<client-remote-id>");
0111         msg.content = "hello world";
0112         Q_EMIT MockPushProvider::s_instance->messageReceived(msg);
0113         QVERIFY(msgSpy.wait());
0114         QCOMPARE(msgSpy.at(0).at(0).toByteArray(), "hello world");
0115 
0116         // reconfigure distributor to a different push provider
0117         dist.setPushProvider(QStringLiteral("Broken"), {});
0118         QVERIFY(stateSpy->wait());
0119         QCOMPARE(con->state(), KUnifiedPush::Connector::Unregistered);
0120         QCOMPARE(con->endpoint(), QString());
0121         QCOMPARE(dist.status(), KUnifiedPush::DistributorStatus::NoSetup);
0122 
0123         dist.setPushProvider(QStringLiteral("Mock"), {});
0124         QVERIFY(stateSpy->wait());
0125         QCOMPARE(con->state(), KUnifiedPush::Connector::Registered);
0126         QCOMPARE(con->endpoint(), QLatin1String("https://localhost/push-endpoint"));
0127 
0128         QVariantMap config;
0129         config.insert(QStringLiteral("setting"), true);
0130         dist.setPushProvider(QStringLiteral("Mock"), config);
0131         QVERIFY(stateSpy->wait());
0132         QCOMPARE(con->state(), KUnifiedPush::Connector::Unregistered);
0133         QCOMPARE(con->endpoint(), QString());
0134         QVERIFY(stateSpy->wait());
0135         QCOMPARE(con->state(), KUnifiedPush::Connector::Registered);
0136         QCOMPARE(con->endpoint(), QLatin1String("https://localhost/push-endpoint"));
0137         QCOMPARE(endpointSpy->size(), 4);
0138 
0139         // connector unregisters
0140         endpointSpy->clear();
0141         con->unregisterClient();
0142         QVERIFY(stateSpy->wait());
0143         QCOMPARE(con->state(), KUnifiedPush::Connector::Unregistered);
0144         QCOMPARE(endpointSpy->size(), 1);
0145         QCOMPARE(con->endpoint(), QString());
0146         QCOMPARE(dist.status(), KUnifiedPush::DistributorStatus::Idle);
0147     }
0148 };
0149 
0150 QTEST_GUILESS_MAIN(ConnectorTest)
0151 
0152 #include "connectortest.moc"
0153 #include "../src/shared/moc_distributorstatus_p.cpp"