1 /*
2  * Copyright (C) 2008-2021 The QXmpp developers
3  *
4  * Authors:
5  *  Manjeet Dahiya
6  *
7  * Source:
8  *  https://github.com/qxmpp-project/qxmpp
9  *
10  * This file is a part of QXmpp library.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  */
23 
24 #include "QXmppStreamFeatures.h"
25 
26 #include "util.h"
27 
28 template<class T>
parsePacketWithStream(T & packet,const QByteArray & xml)29 static void parsePacketWithStream(T &packet, const QByteArray &xml)
30 {
31     QDomDocument doc;
32     const auto wrappedXml =
33         QByteArrayLiteral("<stream:stream xmlns:stream='http://etherx.jabber.org/streams'>") +
34         xml + QByteArrayLiteral("</stream:stream>");
35 
36     QString err;
37     bool parsingSuccess = doc.setContent(wrappedXml, true, &err);
38     if (!err.isNull())
39         qDebug() << err;
40     QVERIFY(parsingSuccess);
41 
42     packet.parse(doc.documentElement().firstChildElement());
43 }
44 
45 class tst_QXmppStreamFeatures : public QObject
46 {
47     Q_OBJECT
48 
49 private slots:
50     void testEmpty();
51     void testRequired();
52     void testFull();
53     void testSetters();
54 };
55 
testEmpty()56 void tst_QXmppStreamFeatures::testEmpty()
57 {
58     const QByteArray xml("<stream:features/>");
59 
60     QXmppStreamFeatures features;
61     parsePacketWithStream(features, xml);
62     QCOMPARE(features.bindMode(), QXmppStreamFeatures::Disabled);
63     QCOMPARE(features.sessionMode(), QXmppStreamFeatures::Disabled);
64     QCOMPARE(features.nonSaslAuthMode(), QXmppStreamFeatures::Disabled);
65     QCOMPARE(features.tlsMode(), QXmppStreamFeatures::Disabled);
66     QCOMPARE(features.clientStateIndicationMode(), QXmppStreamFeatures::Disabled);
67     QCOMPARE(features.registerMode(), QXmppStreamFeatures::Disabled);
68     QCOMPARE(features.preApprovedSubscriptionsSupported(), false);
69     QCOMPARE(features.rosterVersioningSupported(), false);
70     QCOMPARE(features.authMechanisms(), QStringList());
71     QCOMPARE(features.compressionMethods(), QStringList());
72     serializePacket(features, xml);
73 }
74 
testRequired()75 void tst_QXmppStreamFeatures::testRequired()
76 {
77     const QByteArray xml(
78         "<stream:features>"
79         "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\">"
80         "<required/>"
81         "</starttls>"
82         "</stream:features>");
83 
84     QXmppStreamFeatures features;
85     parsePacketWithStream(features, xml);
86     QCOMPARE(features.tlsMode(), QXmppStreamFeatures::Required);
87     serializePacket(features, xml);
88 }
89 
testFull()90 void tst_QXmppStreamFeatures::testFull()
91 {
92     const QByteArray xml("<stream:features>"
93                          "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/>"
94                          "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>"
95                          "<auth xmlns=\"http://jabber.org/features/iq-auth\"/>"
96                          "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>"
97                          "<csi xmlns=\"urn:xmpp:csi:0\"/>"
98                          "<register xmlns=\"http://jabber.org/features/iq-register\"/>"
99                          "<sub xmlns=\"urn:xmpp:features:pre-approval\"/>"
100                          "<ver xmlns=\"urn:xmpp:features:rosterver\"/>"
101                          "<compression xmlns=\"http://jabber.org/features/compress\"><method>zlib</method></compression>"
102                          "<mechanisms xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"><mechanism>PLAIN</mechanism></mechanisms>"
103                          "</stream:features>");
104 
105     QXmppStreamFeatures features;
106     parsePacketWithStream(features, xml);
107     QCOMPARE(features.bindMode(), QXmppStreamFeatures::Enabled);
108     QCOMPARE(features.sessionMode(), QXmppStreamFeatures::Enabled);
109     QCOMPARE(features.nonSaslAuthMode(), QXmppStreamFeatures::Enabled);
110     QCOMPARE(features.tlsMode(), QXmppStreamFeatures::Enabled);
111     QCOMPARE(features.clientStateIndicationMode(), QXmppStreamFeatures::Enabled);
112     QCOMPARE(features.registerMode(), QXmppStreamFeatures::Enabled);
113     QCOMPARE(features.preApprovedSubscriptionsSupported(), true);
114     QCOMPARE(features.authMechanisms(), QStringList() << "PLAIN");
115     QCOMPARE(features.compressionMethods(), QStringList() << "zlib");
116     serializePacket(features, xml);
117 
118     features = QXmppStreamFeatures();
119     features.setBindMode(QXmppStreamFeatures::Enabled);
120     features.setSessionMode(QXmppStreamFeatures::Enabled);
121     features.setNonSaslAuthMode(QXmppStreamFeatures::Enabled);
122     features.setTlsMode(QXmppStreamFeatures::Enabled);
123     features.setClientStateIndicationMode(QXmppStreamFeatures::Enabled);
124     features.setRegisterMode(QXmppStreamFeatures::Enabled);
125     features.setPreApprovedSubscriptionsSupported(true);
126     features.setRosterVersioningSupported(true);
127     features.setAuthMechanisms(QStringList { QStringLiteral("PLAIN") });
128     features.setCompressionMethods(QStringList { QStringLiteral("zlib") });
129     serializePacket(features, xml);
130 }
131 
testSetters()132 void tst_QXmppStreamFeatures::testSetters()
133 {
134     QXmppStreamFeatures features;
135     features.setBindMode(QXmppStreamFeatures::Enabled);
136     QCOMPARE(features.bindMode(), QXmppStreamFeatures::Enabled);
137     features.setSessionMode(QXmppStreamFeatures::Enabled);
138     QCOMPARE(features.sessionMode(), QXmppStreamFeatures::Enabled);
139     features.setNonSaslAuthMode(QXmppStreamFeatures::Enabled);
140     QCOMPARE(features.nonSaslAuthMode(), QXmppStreamFeatures::Enabled);
141     features.setTlsMode(QXmppStreamFeatures::Enabled);
142     QCOMPARE(features.tlsMode(), QXmppStreamFeatures::Enabled);
143     features.setClientStateIndicationMode(QXmppStreamFeatures::Enabled);
144     QCOMPARE(features.clientStateIndicationMode(), QXmppStreamFeatures::Enabled);
145     features.setClientStateIndicationMode(QXmppStreamFeatures::Enabled);
146     QCOMPARE(features.clientStateIndicationMode(), QXmppStreamFeatures::Enabled);
147     features.setRegisterMode(QXmppStreamFeatures::Enabled);
148     QCOMPARE(features.registerMode(), QXmppStreamFeatures::Enabled);
149 
150     features.setAuthMechanisms(QStringList() << "custom-mechanism");
151     QCOMPARE(features.authMechanisms(), QStringList() << "custom-mechanism");
152     features.setCompressionMethods(QStringList() << "compression-methods");
153     QCOMPARE(features.compressionMethods(), QStringList() << "compression-methods");
154 }
155 
156 QTEST_MAIN(tst_QXmppStreamFeatures)
157 #include "tst_qxmppstreamfeatures.moc"
158