// SPDX-FileCopyrightText: 2021 Linus Jahn // // SPDX-License-Identifier: LGPL-2.1-or-later #include "QXmppPubSubAffiliation.h" #include "QXmppPubSubSubscription.h" #include "pubsubutil.h" #include "util.h" #include using Affiliation = QXmppPubSubAffiliation; using AffiliationType = QXmppPubSubAffiliation::Affiliation; using Subscription = QXmppPubSubSubscription; using SubscriptionConfig = QXmppPubSubSubscription::ConfigurationSupport; using SubscriptionState = QXmppPubSubSubscription::State; enum PubSubNamespace { PubSubNs, PubSubEventNs, PubSubOwnerNs, }; Q_DECLARE_METATYPE(PubSubNamespace) template void parsePacket(T &packet, const QByteArray &xml, PubSubNamespace xmlns) { QByteArray newXml; switch (xmlns) { case PubSubNs: newXml = "" + xml + ""; break; case PubSubEventNs: newXml = "" + xml + ""; break; case PubSubOwnerNs: newXml = "" + xml + ""; break; } packet.parse(xmlToDom(newXml).firstChildElement()); } class tst_QXmppPubSub : public QObject { Q_OBJECT private: Q_SLOT void testAffiliation_data(); Q_SLOT void testAffiliation(); Q_SLOT void testIsAffiliation_data(); Q_SLOT void testIsAffiliation(); Q_SLOT void testSubscription_data(); Q_SLOT void testSubscription(); Q_SLOT void testItem(); Q_SLOT void testIsItem_data(); Q_SLOT void testIsItem(); Q_SLOT void testTestItem(); }; void tst_QXmppPubSub::testAffiliation_data() { QTest::addColumn("xml"); QTest::addColumn("type"); QTest::addColumn("jid"); QTest::addColumn("node"); #define ROW(name, xml, type, jid, node) \ QTest::newRow(name) << QByteArrayLiteral(xml) << type << jid << node ROW("owner", "", AffiliationType::Owner, QString(), QString("node1")); ROW("publisher", "", AffiliationType::Publisher, QString(), QString("node2")); ROW("outcast", "", AffiliationType::Outcast, QString(), QString("noise")); ROW("none", "", AffiliationType::None, QString(), QString("stuff")); ROW("with-jid", "", AffiliationType::Owner, QString("snob@qxmpp.org"), QString()); #undef ROW } void tst_QXmppPubSub::testAffiliation() { QFETCH(QByteArray, xml); QFETCH(AffiliationType, type); QFETCH(QString, jid); QFETCH(QString, node); Affiliation affiliation; parsePacket(affiliation, xml); QCOMPARE(affiliation.jid(), jid); QCOMPARE(affiliation.node(), node); QCOMPARE(affiliation.type(), type); serializePacket(affiliation, xml); affiliation = {}; affiliation.setJid(jid); affiliation.setNode(node); affiliation.setType(type); serializePacket(affiliation, xml); } void tst_QXmppPubSub::testIsAffiliation_data() { QTest::addColumn("xml"); QTest::addColumn("accepted"); QTest::newRow("ps-correct") << QByteArrayLiteral("") << true; QTest::newRow("ps-missing-node") << QByteArrayLiteral("") << false; QTest::newRow("ps-invalid-affiliation") << QByteArrayLiteral("") << false; QTest::newRow("psowner-correct") << QByteArrayLiteral("") << true; QTest::newRow("psowner-missing-jid") << QByteArrayLiteral("") << false; QTest::newRow("psowner-invalid-affiliation") << QByteArrayLiteral("") << false; QTest::newRow("invalid-namespace") << QByteArrayLiteral("") << false; } void tst_QXmppPubSub::testIsAffiliation() { QFETCH(QByteArray, xml); QFETCH(bool, accepted); auto dom = xmlToDom(xml).firstChildElement(); QCOMPARE(Affiliation::isAffiliation(dom), accepted); } void tst_QXmppPubSub::testSubscription_data() { QTest::addColumn("xml"); QTest::addColumn("pubSubNs"); QTest::addColumn("state"); QTest::addColumn("jid"); QTest::addColumn("node"); QTest::addColumn("subid"); QTest::addColumn("configSupport"); #define ROW(name, xmlns, xml, state, jid, node, subid, configSupport) \ QTest::newRow(name) << QByteArrayLiteral(xml) << xmlns << state << jid << node << subid << configSupport ROW("subscribed", PubSubNs, "", SubscriptionState::Subscribed, QString("francisco@denmark.lit"), QString("node1"), QString(), SubscriptionConfig::Unavailable); ROW("unconfigured", PubSubNs, "", SubscriptionState::Unconfigured, QString("francisco@denmark.lit"), QString("node5"), QString(), SubscriptionConfig::Unavailable); ROW("subscribed-subid", PubSubNs, "", SubscriptionState::Subscribed, QString("francisco@denmark.lit"), QString("node6"), QString("123-abc"), SubscriptionConfig::Unavailable); ROW("pending", PubSubNs, "", SubscriptionState::Pending, QString("francisco@denmark.lit"), QString("princely_musings"), QString(), SubscriptionConfig::Unavailable); ROW("config-required", PubSubNs, "", SubscriptionState::Unconfigured, QString("francisco@denmark.lit"), QString("princely_musings"), QString(), SubscriptionConfig::Required); ROW("config-available", PubSubNs, "", SubscriptionState::Unconfigured, QString("francisco@denmark.lit"), QString("princely_musings"), QString(), SubscriptionConfig::Available); #undef ROW } void tst_QXmppPubSub::testSubscription() { QFETCH(QByteArray, xml); QFETCH(PubSubNamespace, pubSubNs); QFETCH(SubscriptionState, state); QFETCH(QString, jid); QFETCH(QString, node); QFETCH(QString, subid); QFETCH(SubscriptionConfig, configSupport); QXmppPubSubSubscription sub; parsePacket(sub, xml, pubSubNs); serializePacket(sub, xml); QCOMPARE(sub.state(), state); QCOMPARE(sub.jid(), jid); QCOMPARE(sub.node(), node); QCOMPARE(sub.subId(), subid); QCOMPARE(sub.configurationSupport(), configSupport); switch (configSupport) { case SubscriptionConfig::Unavailable: if (state == SubscriptionState::Unconfigured) { QVERIFY(sub.isConfigurationRequired()); } else { QVERIFY(!sub.isConfigurationRequired()); } QVERIFY(!sub.isConfigurationSupported()); break; case SubscriptionConfig::Available: if (state == SubscriptionState::Unconfigured) { QVERIFY(sub.isConfigurationRequired()); } else { QVERIFY(!sub.isConfigurationRequired()); } QVERIFY(sub.isConfigurationSupported()); break; case SubscriptionConfig::Required: QVERIFY(sub.isConfigurationRequired()); QVERIFY(sub.isConfigurationSupported()); break; } sub = {}; sub.setState(state); sub.setJid(jid); sub.setNode(node); sub.setSubId(subid); sub.setConfigurationSupport(configSupport); serializePacket(sub, xml); } void tst_QXmppPubSub::testItem() { const auto xml = QByteArrayLiteral(""); QXmppPubSubBaseItem item; parsePacket(item, xml); QCOMPARE(item.id(), QStringLiteral("abc1337")); QCOMPARE(item.publisher(), QStringLiteral("lnj@qxmpp.org")); // test serialization with parsed item serializePacket(item, xml); // test serialization with constructor values item = QXmppPubSubBaseItem("abc1337", "lnj@qxmpp.org"); serializePacket(item, xml); // test serialization with setters item = QXmppPubSubBaseItem(); item.setId("abc1337"); item.setPublisher("lnj@qxmpp.org"); serializePacket(item, xml); } void tst_QXmppPubSub::testIsItem_data() { QTest::addColumn("xml"); QTest::addColumn("valid"); QTest::newRow("valid-id-publisher") << QByteArrayLiteral("") << true; QTest::newRow("valid-id") << QByteArrayLiteral("") << true; QTest::newRow("valid-publisher") << QByteArrayLiteral("") << true; QTest::newRow("valid") << QByteArrayLiteral("") << true; QTest::newRow("valid-payload") << QByteArrayLiteral("") << true; QTest::newRow("invalid-tag-name") << QByteArrayLiteral("") << false; } void tst_QXmppPubSub::testIsItem() { QFETCH(QByteArray, xml); QFETCH(bool, valid); QCOMPARE(QXmppPubSubBaseItem::isItem(xmlToDom(xml)), valid); } void tst_QXmppPubSub::testTestItem() { const auto xml = QByteArrayLiteral(""); TestItem item; parsePacket(item, xml); serializePacket(item, xml); QVERIFY(item.parseCalled); QVERIFY(item.serializeCalled); const auto invalidXml = QByteArrayLiteral(""); QVERIFY(TestItem::isItem(xmlToDom(xml))); QVERIFY(!TestItem::isItem(xmlToDom(invalidXml))); } QTEST_MAIN(tst_QXmppPubSub) #include "tst_qxmpppubsub.moc"