// SPDX-FileCopyrightText: 2012 Oliver Goffart // SPDX-FileCopyrightText: 2012 Jeremy Lainé // SPDX-FileCopyrightText: 2022 Melvin Keskin // // SPDX-License-Identifier: LGPL-2.1-or-later #include "QXmppPresence.h" #include "util.h" #include #include class tst_QXmppPresence : public QObject { Q_OBJECT private: Q_SLOT void testPresence(); Q_SLOT void testPresence_data(); Q_SLOT void testPresenceWithCapability(); Q_SLOT void testPresenceWithExtendedAddresses(); Q_SLOT void testPresenceWithMucItem(); Q_SLOT void testPresenceWithMucPassword(); Q_SLOT void testPresenceWithMucSupport(); Q_SLOT void testPresenceWithMuji(); Q_SLOT void testPresenceWithLastUserInteraction(); Q_SLOT void testPresenceWithMix(); Q_SLOT void testPresenceWithVCard(); }; void tst_QXmppPresence::testPresence_data() { QXmppPresence foo; QTest::addColumn("xml"); QTest::addColumn("type"); QTest::addColumn("priority"); QTest::addColumn("statusType"); QTest::addColumn("statusText"); QTest::addColumn("vcardUpdate"); QTest::addColumn("photoHash"); // presence type QTest::newRow("available") << QByteArray("") << int(QXmppPresence::Available) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("unavailable") << QByteArray("") << int(QXmppPresence::Unavailable) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("error") << QByteArray("") << int(QXmppPresence::Error) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("subscribe") << QByteArray("") << int(QXmppPresence::Subscribe) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("unsubscribe") << QByteArray("") << int(QXmppPresence::Unsubscribe) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("subscribed") << QByteArray("") << int(QXmppPresence::Subscribed) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("unsubscribed") << QByteArray("") << int(QXmppPresence::Unsubscribed) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("probe") << QByteArray("") << int(QXmppPresence::Probe) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); // status text + priority QTest::newRow("full") << QByteArray("awayIn a meeting5") << int(QXmppPresence::Available) << 5 << int(QXmppPresence::Away) << "In a meeting" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); // status type QTest::newRow("away") << QByteArray("away") << int(QXmppPresence::Available) << 0 << int(QXmppPresence::Away) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("dnd") << QByteArray("dnd") << int(QXmppPresence::Available) << 0 << int(QXmppPresence::DND) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("chat") << QByteArray("chat") << int(QXmppPresence::Available) << 0 << int(QXmppPresence::Chat) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("xa") << QByteArray("xa") << int(QXmppPresence::Available) << 0 << int(QXmppPresence::XA) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); QTest::newRow("invisible") << QByteArray("invisible") << int(QXmppPresence::Available) << 0 << int(QXmppPresence::Invisible) << "" << int(QXmppPresence::VCardUpdateNone) << QByteArray(); // photo QTest::newRow("vcard-photo") << QByteArray( "" "" "73b908bc" "" "") << int(QXmppPresence::Available) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateValidPhoto) << QByteArray::fromHex("73b908bc"); QTest::newRow("vard-not-ready") << QByteArray( "" "" "") << int(QXmppPresence::Available) << 0 << int(QXmppPresence::Online) << "" << int(QXmppPresence::VCardUpdateNotReady) << QByteArray(); } void tst_QXmppPresence::testPresence() { QFETCH(QByteArray, xml); QFETCH(int, type); QFETCH(int, priority); QFETCH(int, statusType); QFETCH(QString, statusText); QFETCH(int, vcardUpdate); QFETCH(QByteArray, photoHash); // test parsing and serialization after parsing QXmppPresence parsedPresence; parsePacket(parsedPresence, xml); QCOMPARE(int(parsedPresence.type()), type); QCOMPARE(parsedPresence.priority(), priority); QCOMPARE(int(parsedPresence.availableStatusType()), statusType); QCOMPARE(parsedPresence.statusText(), statusText); QCOMPARE(int(parsedPresence.vCardUpdateType()), vcardUpdate); QCOMPARE(parsedPresence.photoHash(), photoHash); serializePacket(parsedPresence, xml); // test serialization from setters QXmppPresence presence; presence.setType(static_cast(type)); presence.setPriority(priority); presence.setAvailableStatusType(static_cast(statusType)); presence.setStatusText(statusText); presence.setVCardUpdateType(static_cast(vcardUpdate)); presence.setPhotoHash(photoHash); serializePacket(presence, xml); } void tst_QXmppPresence::testPresenceWithCapability() { const QByteArray xml( "" "away" "In a meeting" "5" "" "" "73b908bc" "" "" ""); // test parsing and serialization after parsing QXmppPresence presence; parsePacket(presence, xml); QCOMPARE(presence.to(), QString("foo@example.com/QXmpp")); QCOMPARE(presence.from(), QString("bar@example.com/QXmpp")); QCOMPARE(presence.availableStatusType(), QXmppPresence::Away); QCOMPARE(presence.statusText(), QString("In a meeting")); QCOMPARE(presence.priority(), 5); QCOMPARE(presence.photoHash(), QByteArray::fromHex("73b908bc")); QCOMPARE(presence.vCardUpdateType(), QXmppPresence::VCardUpdateValidPhoto); QCOMPARE(presence.capabilityHash(), QString("sha-1")); QCOMPARE(presence.capabilityNode(), QString("https://github.com/qxmpp-project/qxmpp")); QCOMPARE(presence.capabilityVer(), QByteArray::fromBase64("QgayPKawpkPSDYmwT/WM94uAlu0=")); QCOMPARE(presence.extensions().first().tagName(), QStringLiteral("x")); QCOMPARE(presence.extensions().first().attribute(QStringLiteral("xmlns")), QStringLiteral("urn:other:namespace")); serializePacket(presence, xml); // test serialization from setters QXmppPresence presence2; presence2.setTo(QStringLiteral("foo@example.com/QXmpp")); presence2.setFrom(QStringLiteral("bar@example.com/QXmpp")); presence2.setAvailableStatusType(QXmppPresence::Away); presence2.setStatusText(QStringLiteral("In a meeting")); presence2.setPriority(5); presence2.setPhotoHash(QByteArray::fromHex("73b908bc")); presence2.setVCardUpdateType(QXmppPresence::VCardUpdateValidPhoto); presence2.setCapabilityHash(QStringLiteral("sha-1")); presence2.setCapabilityNode(QStringLiteral("https://github.com/qxmpp-project/qxmpp")); presence2.setCapabilityVer(QByteArray::fromBase64("QgayPKawpkPSDYmwT/WM94uAlu0=")); QXmppElement unknownExtension; unknownExtension.setTagName(QStringLiteral("x")); unknownExtension.setAttribute(QStringLiteral("xmlns"), QStringLiteral("urn:other:namespace")); presence2.setExtensions(QXmppElementList() << unknownExtension); serializePacket(presence2, xml); } void tst_QXmppPresence::testPresenceWithExtendedAddresses() { const QByteArray xml( "" "" "
" "
" "" ""); QXmppPresence presence; parsePacket(presence, xml); QCOMPARE(presence.extendedAddresses().size(), 2); QCOMPARE(presence.extendedAddresses()[0].description(), QString()); QCOMPARE(presence.extendedAddresses()[0].jid(), QLatin1String("temas@jabber.org")); QCOMPARE(presence.extendedAddresses()[0].type(), QLatin1String("bcc")); QCOMPARE(presence.extendedAddresses()[1].description(), QString()); QCOMPARE(presence.extendedAddresses()[1].jid(), QLatin1String("jer@jabber.org")); QCOMPARE(presence.extendedAddresses()[1].type(), QLatin1String("bcc")); serializePacket(presence, xml); } void tst_QXmppPresence::testPresenceWithMucItem() { const QByteArray xml( "" "" "" "" "Avaunt, you cullion!" "" "" "" ""); QXmppPresence presence; parsePacket(presence, xml); QCOMPARE(presence.to(), QLatin1String("pistol@shakespeare.lit/harfleur")); QCOMPARE(presence.from(), QLatin1String("harfleur@henryv.shakespeare.lit/pistol")); QCOMPARE(presence.type(), QXmppPresence::Unavailable); QCOMPARE(presence.mucItem().actor(), QLatin1String("fluellen@shakespeare.lit")); QCOMPARE(presence.mucItem().affiliation(), QXmppMucItem::NoAffiliation); QCOMPARE(presence.mucItem().jid(), QString()); QCOMPARE(presence.mucItem().reason(), QLatin1String("Avaunt, you cullion!")); QCOMPARE(presence.mucItem().role(), QXmppMucItem::NoRole); QCOMPARE(presence.mucStatusCodes(), QList() << 307); serializePacket(presence, xml); } void tst_QXmppPresence::testPresenceWithMucPassword() { const QByteArray xml( "" "" "pass" "" ""); QXmppPresence presence; parsePacket(presence, xml); QCOMPARE(presence.to(), QLatin1String("coven@chat.shakespeare.lit/thirdwitch")); QCOMPARE(presence.from(), QLatin1String("hag66@shakespeare.lit/pda")); QCOMPARE(presence.type(), QXmppPresence::Available); QCOMPARE(presence.isMucSupported(), true); QCOMPARE(presence.mucPassword(), QLatin1String("pass")); serializePacket(presence, xml); } void tst_QXmppPresence::testPresenceWithMucSupport() { const QByteArray xml( "" "" ""); QXmppPresence presence; parsePacket(presence, xml); QCOMPARE(presence.to(), QLatin1String("coven@chat.shakespeare.lit/thirdwitch")); QCOMPARE(presence.from(), QLatin1String("hag66@shakespeare.lit/pda")); QCOMPARE(presence.type(), QXmppPresence::Available); QCOMPARE(presence.isMucSupported(), true); QVERIFY(presence.mucPassword().isEmpty()); serializePacket(presence, xml); } void tst_QXmppPresence::testPresenceWithMuji() { const QByteArray xml( "" "" "" "" "" "" ""); QXmppPresence presence1; QVERIFY(!presence1.isPreparingMujiSession()); QVERIFY(presence1.mujiContents().isEmpty()); parsePacket(presence1, xml); QVERIFY(presence1.isPreparingMujiSession()); QCOMPARE(presence1.mujiContents().size(), 2); QCOMPARE(presence1.mujiContents().at(0).name(), QStringLiteral("video")); QCOMPARE(presence1.mujiContents().at(1).name(), QStringLiteral("voice")); serializePacket(presence1, xml); QXmppPresence presence2; presence2.setIsPreparingMujiSession(true); QXmppJingleIq::Content mujiContent1; mujiContent1.setCreator(QStringLiteral("initiator")); mujiContent1.setName(QStringLiteral("video")); QXmppJingleIq::Content mujiContent2; mujiContent2.setCreator(QStringLiteral("initiator")); mujiContent2.setName(QStringLiteral("voice")); presence2.setMujiContents({ mujiContent1, mujiContent2 }); QVERIFY(presence2.isPreparingMujiSession()); QCOMPARE(presence2.mujiContents().size(), 2); QCOMPARE(presence2.mujiContents().at(0).name(), QStringLiteral("video")); QCOMPARE(presence2.mujiContents().at(1).name(), QStringLiteral("voice")); serializePacket(presence2, xml); } void tst_QXmppPresence::testPresenceWithLastUserInteraction() { const QByteArray xml( "" "" ""); QXmppPresence presence; parsePacket(presence, xml); QVERIFY(!presence.lastUserInteraction().isNull()); QVERIFY(presence.lastUserInteraction().isValid()); QCOMPARE(presence.lastUserInteraction(), QDateTime(QDate(1969, 7, 21), QTime(2, 56, 15), Qt::UTC)); serializePacket(presence, xml); QDateTime another(QDate(2025, 2, 5), QTime(15, 32, 8), Qt::UTC); presence.setLastUserInteraction(another); QCOMPARE(presence.lastUserInteraction(), another); } void tst_QXmppPresence::testPresenceWithMix() { const QByteArray xml( "" "dnd" "Making a Brew" "" "hecate@shakespeare.example/UUID-x4r/2491" "thirdwitch" "" ""); QXmppPresence presence; parsePacket(presence, xml); QCOMPARE(presence.mixUserJid(), QString("hecate@shakespeare.example/UUID-x4r/2491")); QCOMPARE(presence.mixUserNick(), QString("thirdwitch")); serializePacket(presence, xml); presence.setMixUserJid("alexander@example.org"); QCOMPARE(presence.mixUserJid(), QString("alexander@example.org")); presence.setMixUserNick("erik"); QCOMPARE(presence.mixUserNick(), QString("erik")); } void tst_QXmppPresence::testPresenceWithVCard() { } QTEST_MAIN(tst_QXmppPresence) #include "tst_qxmpppresence.moc"