diff options
| author | Linus Jahn <lnj@kaidan.im> | 2020-04-05 15:46:40 +0200 |
|---|---|---|
| committer | LNJ <lnj@kaidan.im> | 2020-04-05 16:31:44 +0200 |
| commit | 92ca98fd87764eda452a063bb06611f79829fd69 (patch) | |
| tree | 6818626b7da6072b7ebd6a17cca16ec003010089 | |
| parent | f3aa893f5165feb3020b691434c7ce17119559fd (diff) | |
| download | qxmpp-92ca98fd87764eda452a063bb06611f79829fd69.tar.gz | |
QXmppRosterIq: Add 'approved' attribute from RFC6121
The 'approved' attribute was added in RFC6121 to indicate whether a
pre-approved subscription exists.
| -rw-r--r-- | src/base/QXmppRosterIq.cpp | 42 | ||||
| -rw-r--r-- | src/base/QXmppRosterIq.h | 2 | ||||
| -rw-r--r-- | tests/qxmpprosteriq/tst_qxmpprosteriq.cpp | 57 |
3 files changed, 92 insertions, 9 deletions
diff --git a/src/base/QXmppRosterIq.cpp b/src/base/QXmppRosterIq.cpp index 0397c94d..ef06dd0a 100644 --- a/src/base/QXmppRosterIq.cpp +++ b/src/base/QXmppRosterIq.cpp @@ -159,24 +159,32 @@ void QXmppRosterIq::toXmlElementFromChild(QXmlStreamWriter *writer) const class QXmppRosterIq::ItemPrivate : public QSharedData { public: + ItemPrivate(); + QString bareJid; Item::SubscriptionType type; QString name; // can be subscribe/unsubscribe (attribute "ask") QString subscriptionStatus; QSet<QString> groups; + bool approved; // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements bool isMixChannel = false; QString mixParticipantId; }; +QXmppRosterIq::ItemPrivate::ItemPrivate() + : type(QXmppRosterIq::Item::NotSet), + approved(false) +{ +} + /// /// Constructs a new roster entry. /// QXmppRosterIq::Item::Item() : d(new ItemPrivate) { - d->type = NotSet; } QXmppRosterIq::Item::Item(const QXmppRosterIq::Item &other) = default; @@ -277,6 +285,7 @@ QXmppRosterIq::Item::subscriptionType() const return d->type; } + /// /// Sets the subscription type of the roster entry. /// @@ -287,6 +296,30 @@ void QXmppRosterIq::Item::setSubscriptionType(SubscriptionType type) d->type = type; } +/// +/// Returns whether the item has a pre-approved presence subscription. +/// +/// \since QXmpp 1.3 +/// +bool QXmppRosterIq::Item::isApproved() const +{ + return d->approved; +} + +/// +/// Sets whether the item has a pre-approved presence subscription. +/// +/// This cannot be used to initiate a pre-approved subscription. For this +/// purpose the client must send a <presence/> stanza of type +/// \c subscribed to the user. +/// +/// \since QXmpp 1.3 +/// +void QXmppRosterIq::Item::setIsApproved(bool approved) +{ + d->approved = approved; +} + QString QXmppRosterIq::Item::getSubscriptionTypeStr() const { switch (d->type) { @@ -375,6 +408,11 @@ void QXmppRosterIq::Item::parse(const QDomElement &element) setSubscriptionTypeFromStr(element.attribute(QStringLiteral("subscription"))); setSubscriptionStatus(element.attribute(QStringLiteral("ask"))); + // pre-approved + const QString approved = element.attribute(QStringLiteral("approved")); + d->approved = (approved == QStringLiteral("1") || approved == QStringLiteral("true")); + + // groups QDomElement groupElement = element.firstChildElement(QStringLiteral("group")); while (!groupElement.isNull()) { d->groups << groupElement.text(); @@ -396,6 +434,8 @@ void QXmppRosterIq::Item::toXml(QXmlStreamWriter *writer) const helperToXmlAddAttribute(writer, QStringLiteral("name"), d->name); helperToXmlAddAttribute(writer, QStringLiteral("subscription"), getSubscriptionTypeStr()); helperToXmlAddAttribute(writer, QStringLiteral("ask"), subscriptionStatus()); + if (d->approved) + writer->writeAttribute(QStringLiteral("approved"), QStringLiteral("true")); QSet<QString>::const_iterator i = d->groups.constBegin(); while (i != d->groups.constEnd()) { diff --git a/src/base/QXmppRosterIq.h b/src/base/QXmppRosterIq.h index 6567ba62..77e9b522 100644 --- a/src/base/QXmppRosterIq.h +++ b/src/base/QXmppRosterIq.h @@ -72,12 +72,14 @@ public: QString name() const; QString subscriptionStatus() const; SubscriptionType subscriptionType() const; + bool isApproved() const; void setBareJid(const QString &); void setGroups(const QSet<QString> &); void setName(const QString &); void setSubscriptionStatus(const QString &); void setSubscriptionType(SubscriptionType); + void setIsApproved(bool); // XEP-0405: Mediated Information eXchange (MIX): Participant Server Requirements bool isMixChannel() const; diff --git a/tests/qxmpprosteriq/tst_qxmpprosteriq.cpp b/tests/qxmpprosteriq/tst_qxmpprosteriq.cpp index 57839934..f0fb6f34 100644 --- a/tests/qxmpprosteriq/tst_qxmpprosteriq.cpp +++ b/tests/qxmpprosteriq/tst_qxmpprosteriq.cpp @@ -33,6 +33,8 @@ class tst_QXmppRosterIq : public QObject private slots: void testItem_data(); void testItem(); + void testApproved_data(); + void testApproved(); void testVersion_data(); void testVersion(); void testMixAnnotate(); @@ -44,36 +46,44 @@ void tst_QXmppRosterIq::testItem_data() QTest::addColumn<QByteArray>("xml"); QTest::addColumn<QString>("name"); QTest::addColumn<int>("subscriptionType"); + QTest::addColumn<bool>("approved"); QTest::newRow("none") - << QByteArray(R"(<item jid="foo@example.com" subscription="none"/>)") + << QByteArray(R"(<item jid="foo@example.com" subscription="none" approved="true"/>)") << "" - << int(QXmppRosterIq::Item::None); + << int(QXmppRosterIq::Item::None) + << true; QTest::newRow("from") << QByteArray(R"(<item jid="foo@example.com" subscription="from"/>)") << "" - << int(QXmppRosterIq::Item::From); + << int(QXmppRosterIq::Item::From) + << false; QTest::newRow("to") << QByteArray(R"(<item jid="foo@example.com" subscription="to"/>)") << "" - << int(QXmppRosterIq::Item::To); + << int(QXmppRosterIq::Item::To) + << false; QTest::newRow("both") << QByteArray(R"(<item jid="foo@example.com" subscription="both"/>)") << "" - << int(QXmppRosterIq::Item::Both); + << int(QXmppRosterIq::Item::Both) + << false; QTest::newRow("remove") << QByteArray(R"(<item jid="foo@example.com" subscription="remove"/>)") << "" - << int(QXmppRosterIq::Item::Remove); + << int(QXmppRosterIq::Item::Remove) + << false; QTest::newRow("notset") << QByteArray("<item jid=\"foo@example.com\"/>") << "" - << int(QXmppRosterIq::Item::NotSet); + << int(QXmppRosterIq::Item::NotSet) + << false; QTest::newRow("name") << QByteArray(R"(<item jid="foo@example.com" name="foo bar"/>)") << "foo bar" - << int(QXmppRosterIq::Item::NotSet); + << int(QXmppRosterIq::Item::NotSet) + << false; } void tst_QXmppRosterIq::testItem() @@ -81,6 +91,7 @@ void tst_QXmppRosterIq::testItem() QFETCH(QByteArray, xml); QFETCH(QString, name); QFETCH(int, subscriptionType); + QFETCH(bool, approved); QXmppRosterIq::Item item; parsePacket(item, xml); @@ -89,7 +100,37 @@ void tst_QXmppRosterIq::testItem() QCOMPARE(item.name(), name); QCOMPARE(int(item.subscriptionType()), subscriptionType); QCOMPARE(item.subscriptionStatus(), QString()); + QCOMPARE(item.isApproved(), approved); serializePacket(item, xml); + + item = QXmppRosterIq::Item(); + item.setBareJid("foo@example.com"); + item.setName(name); + item.setSubscriptionType(QXmppRosterIq::Item::SubscriptionType(subscriptionType)); + item.setIsApproved(approved); + serializePacket(item, xml); +} + +void tst_QXmppRosterIq::testApproved_data() +{ + QTest::addColumn<QByteArray>("xml"); + QTest::addColumn<bool>("approved"); + + QTest::newRow("true") << QByteArray(R"(<item jid="foo@example.com" approved="true"/>)") << true; + QTest::newRow("1") << QByteArray(R"(<item jid="foo@example.com" approved="1"/>)") << true; + QTest::newRow("false") << QByteArray(R"(<item jid="foo@example.com" approved="false"/>)") << false; + QTest::newRow("0") << QByteArray(R"(<item jid="foo@example.com" approved="0"/>)") << false; + QTest::newRow("empty") << QByteArray(R"(<item jid="foo@example.com"/>)") << false; +} + +void tst_QXmppRosterIq::testApproved() +{ + QFETCH(QByteArray, xml); + QFETCH(bool, approved); + + QXmppRosterIq::Item item; + parsePacket(item, xml); + QCOMPARE(item.isApproved(), approved); } void tst_QXmppRosterIq::testVersion_data() |
